Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimJwtException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimJwtException.java (.../ClaimJwtException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimJwtException.java (.../ClaimJwtException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,82 +16,35 @@ package io.jsonwebtoken; /** - * ClaimJwtException is a subclass of the {@link JwtException} that is thrown after a validation of an JWT claim failed. + * ClaimJwtException is a subclass of the {@link JwtException} that is thrown after a validation of an JTW claim failed. * * @since 0.5 */ public abstract class ClaimJwtException extends JwtException { - /** - * Deprecated as this is an implementation detail accidentally exposed in the JJWT 0.5 public API. It is no - * longer referenced anywhere in JJWT's implementation and will be removed in a future release. - * - * @deprecated will be removed in a future release. - */ - @Deprecated public static final String INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE = "Expected %s claim to be: %s, but was: %s."; - - /** - * Deprecated as this is an implementation detail accidentally exposed in the JJWT 0.5 public API. It is no - * longer referenced anywhere in JJWT's implementation and will be removed in a future release. - * - * @deprecated will be removed in a future release. - */ - @Deprecated public static final String MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE = "Expected %s claim to be: %s, but was not present in the JWT claims."; - /** - * The header associated with the Claims that failed validation. - */ private final Header header; - /** - * The Claims that failed validation. - */ private final Claims claims; - /** - * Creates a new instance with the specified header, claims and exception message. - * - * @param header the header inspected - * @param claims the claims obtained - * @param message the exception message - */ protected ClaimJwtException(Header header, Claims claims, String message) { super(message); this.header = header; this.claims = claims; } - /** - * Creates a new instance with the specified header, claims and exception message as a result of encountering - * the specified {@code cause}. - * - * @param header the header inspected - * @param claims the claims obtained - * @param message the exception message - * @param cause the exception that caused this ClaimJwtException to be thrown. - */ protected ClaimJwtException(Header header, Claims claims, String message, Throwable cause) { super(message, cause); this.header = header; this.claims = claims; } - /** - * Returns the {@link Claims} that failed validation. - * - * @return the {@link Claims} that failed validation. - */ public Claims getClaims() { return claims; } - /** - * Returns the header associated with the {@link #getClaims() claims} that failed validation. - * - * @return the header associated with the {@link #getClaims() claims} that failed validation. - */ public Header getHeader() { return header; } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Claims.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Claims.java (.../Claims.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Claims.java (.../Claims.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,89 +17,94 @@ import java.util.Date; import java.util.Map; -import java.util.Set; /** - * A JWT Claims set. + * A JWT Claims set. * - *

This is an immutable JSON map with convenient type-safe getters for JWT standard claim names.

+ *

This is ultimately a JSON map and any values can be added to it, but JWT standard names are provided as + * type-safe getters and setters for convenience.

* - *

Additionally, this interface also extends Map<String, Object>, so you can use standard - * {@code Map} accessor/iterator methods as desired, for example:

+ *

Because this interface extends {@code Map<String, Object>}, if you would like to add your own properties, + * you simply use map methods, for example:

* - *
- * claims.get("someKey");
+ *
+ * claims.{@link Map#put(Object, Object) put}("someKey", "someValue");
+ * 
* - *

However, because {@code Claims} instances are immutable, calling any of the map mutation methods - * (such as {@code Map.}{@link Map#put(Object, Object) put}, etc) will result in a runtime exception. The - * {@code Map} interface is implemented specifically for the convenience of working with existing Map-based utilities - * and APIs.

+ *

Creation

* + *

It is easiest to create a {@code Claims} instance by calling one of the + * {@link Jwts#claims() JWTs.claims()} factory methods.

+ * * @since 0.1 */ -public interface Claims extends Map, Identifiable { +public interface Claims extends Map, ClaimsMutator { - /** - * JWT {@code Issuer} claims parameter name: "iss" - */ - String ISSUER = "iss"; + /** JWT {@code Issuer} claims parameter name: "iss" */ + public static final String ISSUER = "iss"; - /** - * JWT {@code Subject} claims parameter name: "sub" - */ - String SUBJECT = "sub"; + /** JWT {@code Subject} claims parameter name: "sub" */ + public static final String SUBJECT = "sub"; - /** - * JWT {@code Audience} claims parameter name: "aud" - */ - String AUDIENCE = "aud"; + /** JWT {@code Audience} claims parameter name: "aud" */ + public static final String AUDIENCE = "aud"; - /** - * JWT {@code Expiration} claims parameter name: "exp" - */ - String EXPIRATION = "exp"; + /** JWT {@code Expiration} claims parameter name: "exp" */ + public static final String EXPIRATION = "exp"; - /** - * JWT {@code Not Before} claims parameter name: "nbf" - */ - String NOT_BEFORE = "nbf"; + /** JWT {@code Not Before} claims parameter name: "nbf" */ + public static final String NOT_BEFORE = "nbf"; - /** - * JWT {@code Issued At} claims parameter name: "iat" - */ - String ISSUED_AT = "iat"; + /** JWT {@code Issued At} claims parameter name: "iat" */ + public static final String ISSUED_AT = "iat"; - /** - * JWT {@code JWT ID} claims parameter name: "jti" - */ - String ID = "jti"; + /** JWT {@code JWT ID} claims parameter name: "jti" */ + public static final String ID = "jti"; /** - * Returns the JWT + * Returns the JWT * iss (issuer) value or {@code null} if not present. * * @return the JWT {@code iss} value or {@code null} if not present. */ String getIssuer(); /** - * Returns the JWT + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setIssuer(String iss); + + /** + * Returns the JWT * sub (subject) value or {@code null} if not present. * * @return the JWT {@code sub} value or {@code null} if not present. */ String getSubject(); /** - * Returns the JWT + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setSubject(String sub); + + /** + * Returns the JWT * aud (audience) value or {@code null} if not present. * * @return the JWT {@code aud} value or {@code null} if not present. */ - Set getAudience(); + String getAudience(); /** - * Returns the JWT + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setAudience(String aud); + + /** + * Returns the JWT * exp (expiration) timestamp or {@code null} if not present. * *

A JWT obtained after this timestamp should not be used.

@@ -109,7 +114,13 @@ Date getExpiration(); /** - * Returns the JWT + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setExpiration(Date exp); + + /** + * Returns the JWT * nbf (not before) timestamp or {@code null} if not present. * *

A JWT obtained before this timestamp should not be used.

@@ -119,7 +130,13 @@ Date getNotBefore(); /** - * Returns the JWT + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setNotBefore(Date nbf); + + /** + * Returns the JWT * iat (issued at) timestamp or {@code null} if not present. * *

If present, this value is the timestamp when the JWT was created.

@@ -129,7 +146,13 @@ Date getIssuedAt(); /** - * Returns the JWTs + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setIssuedAt(Date iat); + + /** + * Returns the JWTs * jti (JWT ID) value or {@code null} if not present. * *

This value is a CaSe-SenSiTiVe unique identifier for the JWT. If available, this value is expected to be @@ -139,28 +162,30 @@ * * @return the JWT {@code jti} value or {@code null} if not present. */ - @Override - // just for JavaDoc specific to the JWT spec String getId(); /** - * Returns the JWTs claim ({@code claimName}) value as a {@code requiredType} instance, or {@code null} if not - * present. + * {@inheritDoc} + */ + @Override //only for better/targeted JavaDoc + Claims setId(String jti); + + /** + * Returns the JWTs claim ({@code claimName}) value as a type {@code requiredType}, or {@code null} if not present. * *

JJWT only converts simple String, Date, Long, Integer, Short and Byte types automatically. Anything more - * complex is expected to be already converted to your desired type by the JSON parser. You may specify a custom - * JSON processor using the {@code JwtParserBuilder}'s - * {@link JwtParserBuilder#json(io.jsonwebtoken.io.Deserializer) json(Deserializer)} method. See the JJWT - * documentation on custom JSON processors for more + * complex is expected to be already converted to your desired type by the JSON + * {@link io.jsonwebtoken.io.Deserializer Deserializer} implementation. You may specify a custom Deserializer for a + * JwtParser with the desired conversion configuration via the {@link JwtParserBuilder#deserializeJsonWith} method. + * See custom JSON processor for more * information. If using Jackson, you can specify custom claim POJO types as described in * custom claim types. * - * @param claimName name of claim + * @param claimName name of claim * @param requiredType the type of the value expected to be returned - * @param the type of the value expected to be returned + * @param the type of the value expected to be returned * @return the JWT {@code claimName} value or {@code null} if not present. * @throws RequiredTypeException throw if the claim value is not null and not of type {@code requiredType} - * @see JJWT JSON Support */ T get(String claimName, Class requiredType); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimsBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimsMutator.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimsMutator.java (.../ClaimsMutator.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ClaimsMutator.java (.../ClaimsMutator.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,9 +15,6 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.lang.NestedCollection; - -import java.util.Collection; import java.util.Date; /** @@ -28,243 +25,78 @@ * @see io.jsonwebtoken.Claims * @since 0.2 */ -public interface ClaimsMutator> { +public interface ClaimsMutator { /** - * Sets the JWT - * iss (issuer) claim. A {@code null} value will remove the property from the JSON Claims map. + * Sets the JWT + * iss (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. - * @deprecated since 0.12.0 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 - * iss (issuer) claim. A {@code null} value will remove the property from the JSON Claims map. + * Sets the JWT + * sub (subject) 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 0.12.0 - */ - T issuer(String iss); - - /** - * Sets the JWT - * sub (subject) claim. A {@code null} value will remove the property from the JSON Claims 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 0.12.0 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 - * sub (subject) claim. A {@code null} value will remove the property from the JSON Claims map. + * Sets the JWT + * aud (audience) 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 0.12.0 - */ - T subject(String sub); - - /** - * Sets the JWT aud (audience) - * claim as a single String, NOT a String array. This method exists only for producing - * JWTs sent to legacy recipients that are unable to interpret the {@code aud} value as a JSON String Array; it is - * strongly recommended to avoid calling this method whenever possible and favor the - * {@link #audience()}.{@link AudienceCollection#add(Object) add(String)} and - * {@link AudienceCollection#add(Collection) add(Collection)} methods instead, as they ensure a single - * deterministic data type for recipients. - * * @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 0.12.0 in favor of {@link #audience()}. This method will be removed before - * the JJWT 1.0 release. */ - @Deprecated T setAudience(String aud); /** - * Configures the JWT - * aud (audience) Claim - * set, quietly ignoring any null, empty, whitespace-only, or existing value already in the set. + * Sets the JWT + * exp (expiration) timestamp. A {@code null} value will remove the property from the JSON map. * - *

When finished, the {@code audience} collection's {@link AudienceCollection#and() and()} method may be used - * to continue configuration. For example:

- *
-     *  Jwts.builder() // or Jwts.claims()
-     *
-     *     .audience().add("anAudience").and() // return parent
-     *
-     *  .subject("Joe") // resume configuration...
-     *  // etc...
-     * 
- * - * @return the {@link AudienceCollection AudienceCollection} to use for {@code aud} configuration. - * @see AudienceCollection AudienceCollection - * @see AudienceCollection#single(String) AudienceCollection.single(String) - * @since 0.12.0 - */ - AudienceCollection audience(); - - /** - * Sets the JWT - * exp (expiration) timestamp claim. A {@code null} value will remove the property from the - * JSON Claims map. - * *

A JWT obtained after this timestamp should not be used.

* * @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 0.12.0 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 - * exp (expiration) timestamp claim. A {@code null} value will remove the property from the - * JSON Claims map. + * Sets the JWT + * nbf (not before) timestamp. A {@code null} value will remove the property from the JSON map. * - *

A JWT obtained after this timestamp should not be used.

- * - * @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 0.12.0 - */ - T expiration(Date exp); - - /** - * Sets the JWT - * nbf (not before) timestamp claim. A {@code null} value will remove the property from the - * JSON Claims map. - * *

A JWT obtained before this timestamp should not be used.

* * @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 0.12.0 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 - * nbf (not before) timestamp claim. A {@code null} value will remove the property from the - * JSON Claims map. + * Sets the JWT + * iat (issued at) timestamp. A {@code null} value will remove the property from the JSON map. * - *

A JWT obtained before this timestamp should not be used.

- * - * @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 0.12.0 - */ - T notBefore(Date nbf); - - /** - * Sets the JWT - * iat (issued at) timestamp claim. A {@code null} value will remove the property from the - * JSON Claims map. - * *

The value is the timestamp when the JWT was created.

* * @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 0.12.0 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 - * iat (issued at) timestamp claim. A {@code null} value will remove the property from the - * JSON Claims map. + * Sets the JWT + * jti (JWT ID) value. A {@code null} value will remove the property from the JSON map. * - *

The value is the timestamp when the JWT was created.

- * - * @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 0.12.0 - */ - T issuedAt(Date iat); - - /** - * Sets the JWT - * jti (JWT ID) claim. A {@code null} value will remove the property from the JSON Claims map. - * *

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.

* * @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 0.12.0 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 - * jti (JWT ID) claim. A {@code null} value will remove the property from the JSON Claims map. - * - *

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.

- * - * @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 0.12.0 - */ - T id(String jti); - - /** - * A {@code NestedCollection} for setting {@link #audience()} values that also allows overriding the collection - * to be a {@link #single(String) single string value} for legacy JWT recipients if necessary. - * - *

Because this interface extends {@link NestedCollection}, the {@link #and()} method may be used to continue - * parent configuration. For example:

- *
-     *  Jwts.builder() // or Jwts.claims()
-     *
-     *     .audience().add("anAudience").and() // return parent
-     *
-     *  .subject("Joe") // resume parent configuration...
-     *  // etc...
- * - * @param

the type of ClaimsMutator to return for method chaining. - * @see #single(String) - * @since 0.12.0 - */ - interface AudienceCollection

extends NestedCollection { - - /** - * Sets the JWT aud (audience) - * Claim as a single String, NOT a String array. This method exists only for producing - * JWTs sent to legacy recipients that are unable to interpret the {@code aud} value as a JSON String Array; - * it is strongly recommended to avoid calling this method whenever possible and favor the - * {@link #add(Object) add(String)} or {@link #add(Collection)} methods instead, as they ensure a single - * deterministic data type for recipients. - * - * @param aud the value to use as the {@code aud} Claim single-String value (and not an array of Strings), or - * {@code null}, empty or whitespace to remove the property from the JSON map. - * @return the instance for method chaining - * @since 0.12.0 - * @deprecated This is technically not deprecated because the JWT RFC mandates support for single string values, - * but it is marked as deprecated to discourage its use when possible. - */ - // DO NOT REMOVE EVER. This is a required RFC feature, but marked as deprecated to discourage its use - @Deprecated - P single(String aud); - } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodec.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodec.java (.../CompressionCodec.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodec.java (.../CompressionCodec.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,56 +15,41 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.io.CompressionAlgorithm; - /** * Compresses and decompresses byte arrays according to a compression algorithm. * - *

"zip" identifier

- * - *

{@code CompressionCodec} extends {@code Identifiable}; the value returned from - * {@link Identifiable#getId() getId()} will be used as the JWT - * zip header value.

- * - * @see Jwts.ZIP#DEF - * @see Jwts.ZIP#GZIP + * @see CompressionCodecs#DEFLATE + * @see CompressionCodecs#GZIP * @since 0.6.0 - * @deprecated since 0.12.0 in favor of {@link io.jsonwebtoken.io.CompressionAlgorithm} to equal the RFC name for this concept. */ -@Deprecated -public interface CompressionCodec extends CompressionAlgorithm { +public interface CompressionCodec { /** - * The algorithm name to use as the JWT - * zip header value. + * The compression algorithm name to use as the JWT's {@code zip} header value. * - * @return the algorithm name to use as the JWT - * zip header value. - * @deprecated since 0.12.0 in favor of {@link #getId()} to ensure congruence with - * all other identifiable algorithms. + * @return the compression algorithm name to use as the JWT's {@code zip} header value. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated String getAlgorithmName(); /** - * Compresses the specified byte array, returning the compressed byte array result. + * Compresses the specified byte array according to the compression {@link #getAlgorithmName() algorithm}. * - * @param content bytes to compress + * @param payload bytes to compress * @return compressed bytes - * @throws CompressionException if the specified byte array cannot be compressed. + * @throws CompressionException if the specified byte array cannot be compressed according to the compression + * {@link #getAlgorithmName() algorithm}. */ - @Deprecated - byte[] compress(byte[] content) throws CompressionException; + byte[] compress(byte[] payload) throws CompressionException; /** - * Decompresses the specified compressed byte array, returning the decompressed byte array result. The - * specified byte array must already be in compressed form. + * Decompresses the specified compressed byte array according to the compression + * {@link #getAlgorithmName() algorithm}. The specified byte array must already be in compressed form + * according to the {@link #getAlgorithmName() algorithm}. * * @param compressed compressed bytes * @return decompressed bytes - * @throws CompressionException if the specified byte array cannot be decompressed. + * @throws CompressionException if the specified byte array cannot be decompressed according to the compression + * {@link #getAlgorithmName() algorithm}. */ - @Deprecated byte[] decompress(byte[] compressed) throws CompressionException; -} +} \ No newline at end of file Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodecResolver.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodecResolver.java (.../CompressionCodecResolver.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodecResolver.java (.../CompressionCodecResolver.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -20,21 +20,17 @@ * can use to decompress the JWT body. * *

JJWT's default {@link JwtParser} implementation supports both the - * {@link Jwts.ZIP#DEF DEFLATE} and {@link Jwts.ZIP#GZIP GZIP} algorithms by default - you do not need to + * {@link CompressionCodecs#DEFLATE DEFLATE} + * and {@link CompressionCodecs#GZIP GZIP} algorithms by default - you do not need to * specify a {@code CompressionCodecResolver} in these cases.

* - *

However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you can implement + *

However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you must implement * your own {@link CompressionCodecResolver} and specify that when - * {@link io.jsonwebtoken.JwtBuilder#compressWith(io.jsonwebtoken.io.CompressionAlgorithm) building} and - * {@link io.jsonwebtoken.JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver) parsing} JWTs.

+ * {@link io.jsonwebtoken.JwtBuilder#compressWith(CompressionCodec) building} and + * {@link io.jsonwebtoken.JwtParser#setCompressionCodecResolver(CompressionCodecResolver) parsing} JWTs.

* - * @see JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver) - * @see JwtParserBuilder#zip() * @since 0.6.0 - * @deprecated in favor of {@link JwtParserBuilder#zip()} */ -@SuppressWarnings("DeprecatedIsStillUsed") -@Deprecated public interface CompressionCodecResolver { /** Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodecs.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodecs.java (.../CompressionCodecs.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionCodecs.java (.../CompressionCodecs.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,15 +15,15 @@ */ package io.jsonwebtoken; +import io.jsonwebtoken.lang.Classes; + /** * Provides default implementations of the {@link CompressionCodec} interface. * - * @see Jwts.ZIP#DEF - * @see Jwts.ZIP#GZIP + * @see #DEFLATE + * @see #GZIP * @since 0.7.0 - * @deprecated in favor of {@link Jwts.ZIP}. */ -@Deprecated //TODO: delete for 1.0 public final class CompressionCodecs { private CompressionCodecs() { @@ -32,25 +32,18 @@ /** * Codec implementing the JWA standard * deflate compression algorithm - * - * @deprecated in favor of {@link Jwts.ZIP#DEF}. */ - @Deprecated - public static final CompressionCodec DEFLATE = (CompressionCodec) Jwts.ZIP.DEF; + public static final CompressionCodec DEFLATE = + Classes.newInstance("io.jsonwebtoken.impl.compression.DeflateCompressionCodec"); /** * Codec implementing the gzip compression algorithm. - * - *

Compatibility Warning

- * + *

Compatibility Warning

*

This is not a standard JWA compression algorithm. Be sure to use this only when you are confident * that all parties accessing the token support the gzip algorithm.

- * - *

If you're concerned about compatibility, the {@link Jwts.ZIP#DEF DEF} code is JWA standards-compliant.

- * - * @deprecated in favor of {@link Jwts.ZIP#GZIP} + *

If you're concerned about compatibility, the {@link #DEFLATE DEFLATE} code is JWA standards-compliant.

*/ - @Deprecated - public static final CompressionCodec GZIP = (CompressionCodec) Jwts.ZIP.GZIP; + public static final CompressionCodec GZIP = + Classes.newInstance("io.jsonwebtoken.impl.compression.GzipCompressionCodec"); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionException.java (.../CompressionException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/CompressionException.java (.../CompressionException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,30 +15,17 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.io.IOException; - /** - * Exception indicating that either compressing or decompressing a JWT body failed. + * Exception indicating that either compressing or decompressing an JWT body failed. * * @since 0.6.0 */ -public class CompressionException extends IOException { +public class CompressionException extends JwtException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public CompressionException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public CompressionException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ExpiredJwtException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ExpiredJwtException.java (.../ExpiredJwtException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ExpiredJwtException.java (.../ExpiredJwtException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,24 +22,15 @@ */ public class ExpiredJwtException extends ClaimJwtException { - /** - * Creates a new instance with the specified header, claims, and explanation message. - * - * @param header jwt header - * @param claims jwt claims (body) - * @param message the message explaining why the exception is thrown. - */ public ExpiredJwtException(Header header, Claims claims, String message) { super(header, claims, message); } /** - * Creates a new instance with the specified header, claims, explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - * @param header jwt header - * @param claims jwt claims (body) + * @param header jwt header + * @param claims jwt claims (body) + * @param message exception message + * @param cause cause * @since 0.5 */ public ExpiredJwtException(Header header, Claims claims, String message, Throwable cause) { Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Header.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Header.java (.../Header.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Header.java (.../Header.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,149 +18,115 @@ import java.util.Map; /** - * A JWT JOSE header. + * A JWT JOSE header. * - *

This is an immutable JSON map with convenient type-safe getters for JWT standard header parameter names.

+ *

This is ultimately a JSON map and any values can be added to it, but JWT JOSE standard names are provided as + * type-safe getters and setters for convenience.

* - *

Because this interface extends Map<String, Object>, you can use standard {@code Map} - * accessor/iterator methods as desired, for example:

+ *

Because this interface extends {@code Map<String, Object>}, if you would like to add your own properties, + * you simply use map methods, for example:

* - *
- * header.get("someKey");
+ *
+ * header.{@link Map#put(Object, Object) put}("headerParamName", "headerParamValue");
+ * 
* - *

However, because {@code Header} instances are immutable, calling any of the map mutation methods - * (such as {@code Map.}{@link Map#put(Object, Object) put}, etc) will result in a runtime exception.

+ *

Creation

* - *

Security

+ *

It is easiest to create a {@code Header} instance by calling one of the + * {@link Jwts#header() JWTs.header()} factory methods.

* - *

The {@code Header} interface itself makes no implications of integrity protection via either digital signatures or - * encryption. Instead, {@link JwsHeader} and {@link JweHeader} represent this information for respective - * {@link Jws} and {@link Jwe} instances.

- * - * @see ProtectedHeader - * @see JwsHeader - * @see JweHeader * @since 0.1 */ -public interface Header extends Map { +public interface Header> extends Map { - /** - * JWT {@code Type} (typ) value: "JWT" - * - * @deprecated since 0.12.0 - this constant is never used within the JJWT codebase. - */ - @Deprecated - String JWT_TYPE = "JWT"; + /** JWT {@code Type} (typ) value: "JWT" */ + public static final String JWT_TYPE = "JWT"; - /** - * JWT {@code Type} header parameter name: "typ" - * @deprecated since 0.12.0 in favor of {@link #getType()}. - */ - @Deprecated - String TYPE = "typ"; + /** JWT {@code Type} header parameter name: "typ" */ + public static final String TYPE = "typ"; - /** - * JWT {@code Content Type} header parameter name: "cty" - * @deprecated since 0.12.0 in favor of {@link #getContentType()}. - */ - @Deprecated - String CONTENT_TYPE = "cty"; + /** JWT {@code Content Type} header parameter name: "cty" */ + public static final String CONTENT_TYPE = "cty"; - /** - * JWT {@code Algorithm} header parameter name: "alg". - * - * @see JWS Algorithm Header - * @see JWE Algorithm Header - * @deprecated since 0.12.0 in favor of {@link #getAlgorithm()}. - */ - @Deprecated - String ALGORITHM = "alg"; + /** JWT {@code Compression Algorithm} header parameter name: "zip" */ + public static final String COMPRESSION_ALGORITHM = "zip"; - /** - * JWT {@code Compression Algorithm} header parameter name: "zip" - * @deprecated since 0.12.0 in favor of {@link #getCompressionAlgorithm()} - */ + /** JJWT legacy/deprecated compression algorithm header parameter name: "calg" + * @deprecated use {@link #COMPRESSION_ALGORITHM} instead. */ @Deprecated - String COMPRESSION_ALGORITHM = "zip"; + public static final String DEPRECATED_COMPRESSION_ALGORITHM = "calg"; /** - * JJWT legacy/deprecated compression algorithm header parameter name: "calg" + * Returns the + * typ (type) header value or {@code null} if not present. * - * @deprecated use {@link #COMPRESSION_ALGORITHM} instead. + * @return the {@code typ} header value or {@code null} if not present. */ - @Deprecated - String DEPRECATED_COMPRESSION_ALGORITHM = "calg"; + String getType(); /** - * Returns the - * typ (Type) header value or {@code null} if not present. + * Sets the JWT + * typ (Type) header value. A {@code null} value will remove the property from the JSON map. * - * @return the {@code typ} header value or {@code null} if not present. + * @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. */ - String getType(); + T setType(String typ); /** - * Returns the - * cty (Content Type) header value or {@code null} if not present. + * Returns the + * cty (Content Type) header value or {@code null} if not present. * - *

The cty (Content Type) Header Parameter is used by applications to declare the - * IANA MediaType of the content - * (the payload). This is intended for use by the application when more than - * one kind of object could be present in the Payload; the application can use this value to disambiguate among - * the different kinds of objects that might be present. It will typically not be used by applications when - * the kind of object is already known. This parameter is ignored by JWT implementations (like JJWT); any - * processing of this parameter is performed by the JWS application. Use of this Header Parameter is OPTIONAL.

+ *

In the normal case where nested signing or encryption operations are not employed (i.e. a compact + * serialization JWT), the use of this header parameter is NOT RECOMMENDED. In the case that nested + * signing or encryption is employed, this Header Parameter MUST be present; in this case, the value MUST be + * {@code JWT}, to indicate that a Nested JWT is carried in this JWT. While media type names are not + * case-sensitive, it is RECOMMENDED that {@code JWT} always be spelled using uppercase characters for + * compatibility with legacy implementations. See + * JWT Appendix A.2 for + * an example of a Nested JWT.

* - *

To keep messages compact in common situations, it is RECOMMENDED that producers omit an - * application/ prefix of a media type value in a {@code cty} Header Parameter when - * no other '/' appears in the media type value. A recipient using the media type value MUST - * treat it as if application/ were prepended to any {@code cty} value not containing a - * '/'. For instance, a {@code cty} value of example SHOULD be used to - * represent the application/example media type, whereas the media type - * application/example;part="1/2" cannot be shortened to - * example;part="1/2".

- * * @return the {@code typ} header parameter value or {@code null} if not present. */ String getContentType(); /** - * Returns the JWT {@code alg} (Algorithm) header value or {@code null} if not present. + * Sets the JWT + * cty (Content Type) header parameter value. A {@code null} value will remove the property from + * the JSON map. * - *
    - *
  • If the JWT is a Signed JWT (a JWS), the - * alg (Algorithm) header parameter identifies the cryptographic algorithm used to secure the - * JWS. Consider using {@link Jwts.SIG}.{@link io.jsonwebtoken.lang.Registry#get(Object) get(id)} - * to convert this string value to a type-safe {@code SecureDigestAlgorithm} instance.
  • - *
  • If the JWT is an Encrypted JWT (a JWE), the - * alg (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 alg value does not represent a - * supported algorithm, or if the recipient does not have a key that can be used with that algorithm. Consider - * using {@link Jwts.KEY}.{@link io.jsonwebtoken.lang.Registry#get(Object) get(id)} to convert this string value - * to a type-safe {@link io.jsonwebtoken.security.KeyAlgorithm KeyAlgorithm} instance.
  • - *
+ *

In the normal case where nested signing or encryption operations are not employed (i.e. a compact + * serialization JWT), the use of this header parameter is NOT RECOMMENDED. In the case that nested + * signing or encryption is employed, this Header Parameter MUST be present; in this case, the value MUST be + * {@code JWT}, to indicate that a Nested JWT is carried in this JWT. While media type names are not + * case-sensitive, it is RECOMMENDED that {@code JWT} always be spelled using uppercase characters for + * compatibility with legacy implementations. See + * JWT Appendix A.2 for + * an example of a Nested JWT.

* - * @return the {@code alg} header value or {@code null} if not present. This will always be - * {@code non-null} on validly constructed JWT instances, but could be {@code null} during construction. - * @since 0.12.0 + * @param cty the JWT JOSE {@code cty} header value or {@code null} to remove the property from the JSON map. */ - String getAlgorithm(); + T setContentType(String cty); /** - * Returns the JWT zip - * (Compression Algorithm) header parameter value or {@code null} if not present. + * Returns the JWT zip (Compression Algorithm) header value or {@code null} if not present. * - *

Compatibility Note

- * - *

While the JWT family of specifications only defines the zip 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 if you use compression when creating a JWS token, other libraries may not be able to - * parse the JWS. However, compression when creating JWE tokens should be universally accepted for any library - * that supports JWE.

- * * @return the {@code zip} header parameter value or {@code null} if not present. * @since 0.6.0 */ String getCompressionAlgorithm(); + + /** + * Sets the JWT zip (Compression Algorithm) header parameter value. A {@code null} value will remove + * the property from the JSON map. + *

+ *

The compression algorithm is NOT part of the JWT specification + * and must be used carefully since, is not expected that other libraries (including previous versions of this one) + * be able to deserialize a compressed JTW body correctly.

+ * + * @param zip the JWT compression algorithm {@code zip} value or {@code null} to remove the property from the JSON map. + * @since 0.6.0 + */ + T setCompressionAlgorithm(String zip); + } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/HeaderMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Identifiable.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/IncorrectClaimException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/IncorrectClaimException.java (.../IncorrectClaimException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/IncorrectClaimException.java (.../IncorrectClaimException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -23,30 +23,11 @@ */ public class IncorrectClaimException extends InvalidClaimException { - /** - * Creates a new instance with the specified header, claims and explanation message. - * - * @param header the header inspected - * @param claims the claims with the incorrect claim value - * @param claimName the name of the claim that could not be validated - * @param claimValue the value of the claim that could not be validated - * @param message the exception message - */ - public IncorrectClaimException(Header header, Claims claims, String claimName, Object claimValue, String message) { - super(header, claims, claimName, claimValue, message); + public IncorrectClaimException(Header header, Claims claims, String message) { + super(header, claims, message); } - /** - * Creates a new instance with the specified header, claims, explanation message and underlying cause. - * - * @param header the header inspected - * @param claims the claims with the incorrect claim value - * @param claimName the name of the claim that could not be validated - * @param claimValue the value of the claim that could not be validated - * @param message the exception message - * @param cause the underlying cause that resulted in this exception being thrown - */ - public IncorrectClaimException(Header header, Claims claims, String claimName, Object claimValue, String message, Throwable cause) { - super(header, claims, claimName, claimValue, message, cause); + public IncorrectClaimException(Header header, Claims claims, String message, Throwable cause) { + super(header, claims, message, cause); } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/InvalidClaimException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/InvalidClaimException.java (.../InvalidClaimException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/InvalidClaimException.java (.../InvalidClaimException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -21,66 +21,35 @@ * * @see IncorrectClaimException * @see MissingClaimException + * * @since 0.6 */ public class InvalidClaimException extends ClaimJwtException { - /** - * The name of the invalid claim. - */ - private final String claimName; + private String claimName; + private Object claimValue; - /** - * The claim value that could not be validated. - */ - private final Object claimValue; - - /** - * Creates a new instance with the specified header, claims and explanation message. - * - * @param header the header inspected - * @param claims the claims obtained - * @param claimName the name of the claim that could not be validated - * @param claimValue the value of the claim that could not be validated - * @param message the exception message - */ - protected InvalidClaimException(Header header, Claims claims, String claimName, Object claimValue, String message) { + protected InvalidClaimException(Header header, Claims claims, String message) { super(header, claims, message); - this.claimName = claimName; - this.claimValue = claimValue; } - /** - * Creates a new instance with the specified header, claims, explanation message and underlying cause. - * - * @param header the header inspected - * @param claims the claims obtained - * @param claimName the name of the claim that could not be validated - * @param claimValue the value of the claim that could not be validated - * @param message the exception message - * @param cause the underlying cause that resulted in this exception being thrown - */ - protected InvalidClaimException(Header header, Claims claims, String claimName, Object claimValue, String message, Throwable cause) { + protected InvalidClaimException(Header header, Claims claims, String message, Throwable cause) { super(header, claims, message, cause); - this.claimName = claimName; - this.claimValue = claimValue; } - /** - * Returns the name of the invalid claim. - * - * @return the name of the invalid claim. - */ public String getClaimName() { return claimName; } - /** - * Returns the claim value that could not be validated. - * - * @return the claim value that could not be validated. - */ + public void setClaimName(String claimName) { + this.claimName = claimName; + } + public Object getClaimValue() { return claimValue; } + + public void setClaimValue(Object claimValue) { + this.claimValue = claimValue; + } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwe.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JweHeader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JweHeaderMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jws.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jws.java (.../Jws.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jws.java (.../Jws.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,49 +18,11 @@ /** * An expanded (not compact/serialized) Signed JSON Web Token. * - * @param

the type of the JWS payload, either a byte[] or a {@link Claims} instance. + * @param the type of the JWS body contents, either a String or a {@link Claims} instance. + * * @since 0.1 */ -public interface Jws

extends ProtectedJwt { +public interface Jws extends Jwt { - /** - * Visitor implementation that ensures the visited JWT is a JSON Web Signature ('JWS') message with a - * cryptographically authenticated/verified {@code byte[]} array payload, and rejects all others with an - * {@link UnsupportedJwtException}. - * - * @see SupportedJwtVisitor#onVerifiedContent(Jws) - * @since 0.12.0 - */ - @SuppressWarnings("UnnecessaryModifier") - public static final JwtVisitor> CONTENT = new SupportedJwtVisitor>() { - @Override - public Jws onVerifiedContent(Jws jws) { - return jws; - } - }; - - /** - * Visitor implementation that ensures the visited JWT is a JSON Web Signature ('JWS') message with a - * cryptographically authenticated/verified {@link Claims} payload, and rejects all others with an - * {@link UnsupportedJwtException}. - * - * @see SupportedJwtVisitor#onVerifiedClaims(Jws) - * @since 0.12.0 - */ - @SuppressWarnings("UnnecessaryModifier") - public static final JwtVisitor> CLAIMS = new SupportedJwtVisitor>() { - @Override - public Jws onVerifiedClaims(Jws jws) { - return jws; - } - }; - - /** - * Returns the verified JWS signature as a Base64Url string. - * - * @return the verified JWS signature as a Base64Url string. - * @deprecated since 0.12.0 in favor of {@link #getDigest() getDigest()}. - */ - @Deprecated - String getSignature(); //TODO for 1.0: return a byte[] + String getSignature(); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwsHeader.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwsHeader.java (.../JwsHeader.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwsHeader.java (.../JwsHeader.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,92 +16,92 @@ package io.jsonwebtoken; /** - * A JWS header. + * A JWS header. * + * @param header type * @since 0.1 */ -public interface JwsHeader extends ProtectedHeader { +public interface JwsHeader> extends Header { - /** - * JWS Algorithm Header name: the string literal alg - * - * @deprecated since 0.12.0 in favor of {@link #getAlgorithm()} - */ - @Deprecated - String ALGORITHM = "alg"; + /** JWS {@code Algorithm} header parameter name: "alg" */ + public static final String ALGORITHM = "alg"; - /** - * JWS JWK Set URL Header name: the string literal jku - * - * @deprecated since 0.12.0 in favor of {@link #getJwkSetUrl()} - */ - @Deprecated - String JWK_SET_URL = "jku"; + /** JWS {@code JWT Set URL} header parameter name: "jku" */ + public static final String JWK_SET_URL = "jku"; - /** - * JWS JSON Web Key Header name: the string literal jwk - * - * @deprecated since 0.12.0 in favor of {@link #getJwk()} - */ - @Deprecated - String JSON_WEB_KEY = "jwk"; + /** JWS {@code JSON Web Key} header parameter name: "jwk" */ + public static final String JSON_WEB_KEY = "jwk"; - /** - * JWS Key ID Header name: the string literal kid - * - * @deprecated since 0.12.0 in favor of {@link #getKeyId()} - */ - @Deprecated - String KEY_ID = "kid"; + /** JWS {@code Key ID} header parameter name: "kid" */ + public static final String KEY_ID = "kid"; - /** - * JWS X.509 URL Header name: the string literal x5u - * - * @deprecated since 0.12.0 in favor of {@link #getX509Url()} - */ - @Deprecated - String X509_URL = "x5u"; + /** JWS {@code X.509 URL} header parameter name: "x5u" */ + public static final String X509_URL = "x5u"; - /** - * JWS X.509 Certificate Chain Header name: the string literal x5c - * - * @deprecated since 0.12.0 in favor of {@link #getX509Chain()} - */ - @Deprecated - String X509_CERT_CHAIN = "x5c"; + /** JWS {@code X.509 Certificate Chain} header parameter name: "x5c" */ + public static final String X509_CERT_CHAIN = "x5c"; + /** JWS {@code X.509 Certificate SHA-1 Thumbprint} header parameter name: "x5t" */ + public static final String X509_CERT_SHA1_THUMBPRINT = "x5t"; + + /** JWS {@code X.509 Certificate SHA-256 Thumbprint} header parameter name: "x5t#S256" */ + public static final String X509_CERT_SHA256_THUMBPRINT = "x5t#S256"; + + /** JWS {@code Critical} header parameter name: "crit" */ + public static final String CRITICAL = "crit"; + /** - * JWS X.509 Certificate SHA-1 Thumbprint Header name: the string literal x5t + * Returns the JWS + * alg (algorithm) header value or {@code null} if not present. * - * @deprecated since 0.12.0 in favor of {@link #getX509Sha1Thumbprint()} + *

The algorithm header parameter identifies the cryptographic algorithm used to secure the JWS. Consider + * using {@link io.jsonwebtoken.SignatureAlgorithm#forName(String) SignatureAlgorithm.forName} to convert this + * string value to a type-safe enum instance.

+ * + * @return the JWS {@code alg} header value or {@code null} if not present. This will always be + * {@code non-null} on validly constructed JWS instances, but could be {@code null} during construction. */ - @Deprecated - String X509_CERT_SHA1_THUMBPRINT = "x5t"; + String getAlgorithm(); /** - * JWS X.509 Certificate SHA-256 Thumbprint Header name: the string literal x5t#S256 + * Sets the JWT + * alg (Algorithm) header value. A {@code null} value will remove the property from the JSON map. * - * @deprecated since 0.12.0 in favor of {@link #getX509Sha256Thumbprint()} + *

The algorithm header parameter identifies the cryptographic algorithm used to secure the JWS. Consider + * using a type-safe {@link io.jsonwebtoken.SignatureAlgorithm SignatureAlgorithm} instance and using its + * {@link io.jsonwebtoken.SignatureAlgorithm#getValue() value} as the argument to this method.

+ * + * @param alg the JWS {@code alg} header value or {@code null} to remove the property from the JSON map. + * @return the {@code Header} instance for method chaining. */ - @Deprecated - String X509_CERT_SHA256_THUMBPRINT = "x5t#S256"; + T setAlgorithm(String alg); /** - * JWS Critical Header name: the string literal crit + * Returns the JWS + * kid (Key ID) header value or {@code null} if not present. * - * @deprecated since 0.12.0 in favor of {@link #getCritical()} + *

The keyId header parameter is a hint indicating which key was used to secure the JWS. This parameter allows + * originators to explicitly signal a change of key to recipients. The structure of the keyId value is + * unspecified.

+ * + *

When used with a JWK, the keyId value is used to match a JWK {@code keyId} parameter value.

+ * + * @return the JWS {@code kid} header value or {@code null} if not present. */ - @Deprecated - String CRITICAL = "crit"; + String getKeyId(); /** - * Returns {@code true} if the payload is Base64Url-encoded per standard JWS rules, or {@code false} if the - * RFC 7797: JSON Web Signature (JWS) Unencoded Payload - * Option has been specified. + * Sets the JWT + * kid (Key ID) header value. A {@code null} value will remove the property from the JSON map. * - * @return {@code true} if the payload is Base64Url-encoded per standard JWS rules, or {@code false} if the - * RFC 7797: JSON Web Signature (JWS) Unencoded Payload - * Option has been specified. + *

The keyId header parameter is a hint indicating which key was used to secure the JWS. This parameter allows + * originators to explicitly signal a change of key to recipients. The structure of the keyId value is + * unspecified.

+ * + *

When used with a JWK, the keyId value is used to match a JWK {@code keyId} parameter value.

+ * + * @param kid the JWS {@code kid} header value or {@code null} to remove the property from the JSON map. + * @return the {@code Header} instance for method chaining. */ - boolean isPayloadEncoded(); + T setKeyId(String kid); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwt.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwt.java (.../Jwt.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwt.java (.../Jwt.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,79 +18,23 @@ /** * An expanded (not compact/serialized) JSON Web Token. * - * @param the type of the JWT header - * @param

the type of the JWT payload, either a content byte array or a {@link Claims} instance. + * @param the type of the JWT body contents, either a String or a {@link Claims} instance. + * * @since 0.1 */ -public interface Jwt { +public interface Jwt { /** - * Visitor implementation that ensures the visited JWT is an unsecured content JWT (one not cryptographically - * signed or encrypted) and rejects all others with an {@link UnsupportedJwtException}. - * - * @see SupportedJwtVisitor#onUnsecuredContent(Jwt) - * @since 0.12.0 - */ - @SuppressWarnings("UnnecessaryModifier") - public static final JwtVisitor> UNSECURED_CONTENT = new SupportedJwtVisitor>() { - @Override - public Jwt onUnsecuredContent(Jwt jwt) { - return jwt; - } - }; - - /** - * Visitor implementation that ensures the visited JWT is an unsecured {@link Claims} JWT (one not - * cryptographically signed or encrypted) and rejects all others with an {@link UnsupportedJwtException}. - * - * @see SupportedJwtVisitor#onUnsecuredClaims(Jwt) - * @since 0.12.0 - */ - @SuppressWarnings("UnnecessaryModifier") - public static final JwtVisitor> UNSECURED_CLAIMS = new SupportedJwtVisitor>() { - @Override - public Jwt onUnsecuredClaims(Jwt jwt) { - return jwt; - } - }; - - /** * Returns the JWT {@link Header} or {@code null} if not present. * * @return the JWT {@link Header} or {@code null} if not present. */ H getHeader(); /** - * Returns the JWT payload, either a {@code byte[]} or a {@code Claims} instance. Use - * {@link #getPayload()} instead, as this method will be removed prior to the 1.0 release. + * Returns the JWT body, either a {@code String} or a {@code Claims} instance. * - * @return the JWT payload, either a {@code byte[]} or a {@code Claims} instance. - * @deprecated since 0.12.0 because it has been renamed to {@link #getPayload()}. 'Payload' (not - * body) is what the JWT specifications call this property, so it has been renamed to reflect the correct JWT - * nomenclature/taxonomy. + * @return the JWT body, either a {@code String} or a {@code Claims} instance. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - P getBody(); // TODO: remove for 1.0 - - /** - * Returns the JWT payload, either a {@code byte[]} or a {@code Claims} instance. If the payload is a byte - * array, and if the JWT creator set the (optional) {@link Header#getContentType() contentType} header - * value, the application may inspect the {@code contentType} value to determine how to convert the byte array to - * the final content type as desired. - * - * @return the JWT payload, either a {@code byte[]} or a {@code Claims} instance. - * @since 0.12.0 - */ - P getPayload(); - - /** - * Invokes the specified {@code visitor}'s appropriate type-specific {@code visit} method based on this JWT's type. - * - * @param visitor the visitor to invoke. - * @param the value type returned from the {@code visit} method. - * @return the value returned from visitor's {@code visit} method implementation. - */ - T accept(JwtVisitor visitor); + B getBody(); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtBuilder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtBuilder.java (.../JwtBuilder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtBuilder.java (.../JwtBuilder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,732 +15,370 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.io.CompressionAlgorithm; import io.jsonwebtoken.io.Decoder; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.Encoder; import io.jsonwebtoken.io.Serializer; -import io.jsonwebtoken.lang.Conjunctor; -import io.jsonwebtoken.lang.MapMutator; -import io.jsonwebtoken.security.AeadAlgorithm; import io.jsonwebtoken.security.InvalidKeyException; -import io.jsonwebtoken.security.KeyAlgorithm; import io.jsonwebtoken.security.Keys; -import io.jsonwebtoken.security.Password; -import io.jsonwebtoken.security.SecureDigestAlgorithm; -import io.jsonwebtoken.security.WeakKeyException; -import io.jsonwebtoken.security.X509Builder; - -import javax.crypto.SecretKey; -import java.io.InputStream; -import java.io.OutputStream; import java.security.Key; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.SecureRandom; -import java.security.interfaces.ECKey; -import java.security.interfaces.RSAKey; import java.util.Date; import java.util.Map; /** - * A builder for constructing Unprotected JWTs, Signed JWTs (aka 'JWS's) and Encrypted JWTs (aka 'JWE's). + * A builder for constructing JWTs. * * @since 0.1 */ public interface JwtBuilder extends ClaimsMutator { - /** - * Sets the JCA Provider to use during cryptographic signing or encryption operations, or {@code null} if the - * JCA subsystem preferred provider should be used. - * - * @param provider the JCA Provider to use during cryptographic signing or encryption operations, or {@code null} if the - * JCA subsystem preferred provider should be used. - * @return the builder for method chaining. - * @since 0.12.0 - */ - JwtBuilder provider(Provider provider); + //replaces any existing header with the specified header. /** - * Sets the {@link SecureRandom} to use during cryptographic signing or encryption operations, or {@code null} if - * a default {@link SecureRandom} should be used. + * Sets (and replaces) any existing header with the specified header. If you do not want to replace the existing + * header and only want to append to it, use the {@link #setHeaderParams(java.util.Map)} method instead. * - * @param secureRandom the {@link SecureRandom} to use during cryptographic signing or encryption operations, or - * {@code null} if a default {@link SecureRandom} should be used. + * @param header the header to set (and potentially replace any existing header). * @return the builder for method chaining. - * @since 0.12.0 */ - JwtBuilder random(SecureRandom secureRandom); + JwtBuilder setHeader(Header header); /** - * 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: + * Sets (and replaces) any existing header with the specified header. If you do not want to replace the existing + * header and only want to append to it, use the {@link #setHeaderParams(java.util.Map)} method instead. * - *

-     * String jwt = Jwts.builder()
-     *
-     *     .header()
-     *         .keyId("keyId")
-     *         .add("aName", aValue)
-     *         .add(myHeaderMap)
-     *         // ... etc ...
-     *         .{@link BuilderHeader#and() and()} //return back to the JwtBuilder
-     *
-     *     .subject("Joe") // resume JwtBuilder calls
-     *     // ... etc ...
-     *     .compact();
- * - * @return the {@link BuilderHeader} to use for header construction. - * @since 0.12.0 - */ - BuilderHeader header(); - - /** - * 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: - * - *
-     * {@link #header()}.{@link MapMutator#empty() empty()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}
- * - *

If you do not want to replace the existing header and only want to append to it, - * call {@link #header()}.{@link io.jsonwebtoken.lang.MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()} instead.

- * - * @param map the name/value pairs to set as (and potentially replace) the constructed JWT header. + * @param header the header to set (and potentially replace any existing header). * @return the builder for method chaining. - * @deprecated since 0.12.0 in favor of - * {@link #header()}.{@link MapMutator#empty() empty()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()} - * (to replace all header parameters) or - * {@link #header()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()} - * to only append the {@code map} entries. This method will be removed before the 1.0 release. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - JwtBuilder setHeader(Map map); + JwtBuilder setHeader(Map header); /** - * 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: - *
-     * {@link #header()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}
+ * 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. * * @param params the header name/value pairs to append to the header. * @return the builder for method chaining. - * @deprecated since 0.12.0 in favor of - * {@link #header()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}. - * This method will be removed before the 1.0 release. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - JwtBuilder setHeaderParams(Map params); + JwtBuilder setHeaderParams(Map params); + //sets the specified header parameter, overwriting any previous value under the same name. + /** - * 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: - *
-     * {@link #header()}.{@link MapMutator#add(Object, Object) add(name, value)}.{@link BuilderHeader#and() and()}
+ * 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. * * @param name the header parameter name * @param value the header parameter value * @return the builder for method chaining. - * @deprecated since 0.12.0 in favor of - * {@link #header()}.{@link MapMutator#add(Object, Object) add(name, value)}.{@link BuilderHeader#and() and()}. - * This method will be removed before the 1.0 release. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated JwtBuilder setHeaderParam(String name, Object value); /** - * Since JJWT 0.12.0, this is an alias for {@link #content(String)}. This method will be removed - * before the 1.0 release. + * Sets the JWT's payload to be a plaintext (non-JSON) string. If you want the JWT body to be JSON, use the + * {@link #setClaims(Claims)} or {@link #setClaims(java.util.Map)} methods instead. * - * @param payload the string used to set UTF-8-encoded bytes as the JWT payload. + *

The payload and claims properties are mutually exclusive - only one of the two may be used.

+ * + * @param payload the plaintext (non-JSON) string that will be the body of the JWT. * @return the builder for method chaining. - * @see #content(String) - * @deprecated since 0.12.0 in favor of {@link #content(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 string's UTF-8 bytes. This is a convenience method semantically - * equivalent to calling: + * Sets the JWT payload to be a JSON Claims instance. If you do not want the JWT body to be JSON and instead want + * it to be a plaintext string, use the {@link #setPayload(String)} method instead. * - *
-     * {@link #content(byte[]) content}(payload.getBytes(StandardCharsets.UTF_8))
+ *

The payload and claims properties are mutually exclusive - only one of the two may be used.

* - *

Content Type Recommendation

- * - *

Unless you are confident that the JWT recipient will always know to convert the payload bytes - * to a UTF-8 string without additional metadata, it is strongly recommended to use the - * {@link #content(String, 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 payload bytes without ambiguity.

- * - *

Mutually Exclusive Claims and Content

- * - *

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. If you want the - * JWT payload to be JSON claims, use the {@link #claim(String, Object)} or {@link #claims()} methods instead.

- * - * @param content the content string to use for the JWT payload + * @param claims the JWT claims to be set as the JWT body. * @return the builder for method chaining. - * @see #content(String, String) - * @see #content(byte[], String) - * @see #content(InputStream, String) - * @since 0.12.0 */ - JwtBuilder content(String content); + JwtBuilder setClaims(Claims claims); /** - * Sets the JWT payload to be the specified content byte array. This is a convenience method semantically - * equivalent to calling: - *
-     * {@link #content(InputStream) content}(new ByteArrayInputStream(content))
+ * Sets the JWT payload to be a JSON Claims instance populated by the specified name/value pairs. If you do not + * want the JWT body to be JSON and instead want it to be a plaintext string, use the {@link #setPayload(String)} + * method instead. * - *

Content Type Recommendation

+ *

The payload* and claims* properties are mutually exclusive - only one of the two may be used.

* - *

Unless you are confident that the JWT recipient will always know how to use the payload bytes - * without additional metadata, it is strongly recommended to also set the - * {@link Header#getContentType() contentType} header. For example:

- * - *
-     * content(bytes).{@link #header() header()}.{@link HeaderMutator#contentType(String) contentType(cty)}.{@link BuilderHeader#and() and()}
- * - *

This ensures a JWT recipient can inspect the {@code cty} header to know how to handle the payload bytes - * without ambiguity.

- * - *

Mutually Exclusive Claims and Content

- * - *

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. If you want the - * JWT payload to be JSON claims, use the {@link #claim(String, Object)} or {@link #claims()} methods instead.

- * - * @param content the content byte array to use as the JWT payload + * @param claims the JWT claims to be set as the JWT body. * @return the builder for method chaining. - * @see #content(byte[], String) - * @since 0.12.0 */ - JwtBuilder content(byte[] content); + JwtBuilder setClaims(Map claims); /** - * Sets the JWT payload to be the bytes in the specified content stream. + * 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. * - *

Content Type Recommendation

+ *

The payload and claims properties are mutually exclusive - only one of the two may be used.

* - *

Unless you are confident that the JWT recipient will always know how to use the payload bytes - * without additional metadata, it is strongly recommended to also set the - * {@link HeaderMutator#contentType(String) contentType} header. For example:

- * - *
-     * content(in).{@link #header() header()}.{@link HeaderMutator#contentType(String) contentType(cty)}.{@link BuilderHeader#and() and()}
- * - *

This ensures a JWT recipient can inspect the {@code cty} header to know how to handle the payload bytes - * without ambiguity.

- * - *

Mutually Exclusive Claims and Content

- * - *

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. If you want the - * JWT payload to be JSON claims, use the {@link #claim(String, Object)} or {@link #claims()} methods instead.

- * - * @param in the input stream containing the bytes to use as the JWT payload + * @param claims the JWT claims to be added to the JWT body. * @return the builder for method chaining. - * @see #content(byte[], String) - * @since 0.12.0 + * @since 0.8 */ - JwtBuilder content(InputStream in); + JwtBuilder addClaims(Map claims); /** - * Sets the JWT payload to be the specified String's UTF-8 bytes, and also sets the - * {@link HeaderMutator#contentType(String) contentType} header value to a compact {@code cty} IANA Media Type - * identifier to indicate the data format of the resulting 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. This is a - * convenience method semantically equivalent to: + * Sets the JWT Claims + * iss (issuer) value. A {@code null} value will remove the property from the Claims. * - *
-     * {@link #content(String) content(content)}.{@link #header()}.{@link HeaderMutator#contentType(String) contentType(cty)}.{@link BuilderHeader#and() and()}
+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setIssuer(String) issuer} field with the specified value. This allows you to write + * code like this:

* - *

Compact Media Type Identifier

+ *
+     * String jwt = Jwts.builder().setIssuer("Joe").compact();
+     * 
* - *

This method will automatically remove any application/ prefix from the - * {@code cty} string if possible according to the rules defined in the last paragraph of - * RFC 7517, Section 4.1.10:

+ *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setIssuer("Joe");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

* - *
-     *     To keep messages compact in common situations, it is RECOMMENDED that
-     *     producers omit an "application/" prefix of a media type value in a
-     *     "cty" Header Parameter when no other '/' appears in the media type
-     *     value.  A recipient using the media type value MUST treat it as if
-     *     "application/" were prepended to any "cty" value not containing a
-     *     '/'.  For instance, a "cty" value of "example" SHOULD be used to
-     *     represent the "application/example" media type, whereas the media
-     *     type "application/example;part="1/2"" cannot be shortened to
-     *     "example;part="1/2"".
- * - *

JJWT performs the reverse during JWT parsing: {@link Header#getContentType()} will automatically prepend the - * {@code application/} prefix if the parsed {@code cty} value does not contain a '/' character (as - * mandated by the RFC language above). This ensures application developers can use and read standard IANA Media - * Type identifiers without needing JWT-specific prefix conditional logic in application code. - *

- * - *

Mutually Exclusive Claims and Content

- * - *

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. If you want the - * JWT payload to be JSON claims, use the {@link #claim(String, Object)} or {@link #claims()} methods instead.

- * - * @param content the content byte array that will be the JWT payload. Cannot be null or empty. - * @param cty the content type (media type) identifier attributed to the byte array. Cannot be null or empty. - * @return the builder for method chaining. - * @throws IllegalArgumentException if either {@code content} or {@code cty} are null or empty. - * @since 0.12.0 + * @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 */ - JwtBuilder content(String content, String cty) throws IllegalArgumentException; + @Override + //only for better/targeted JavaDoc + JwtBuilder setIssuer(String iss); /** - * Sets the JWT payload to be the specified byte array, and also sets the - * {@link HeaderMutator#contentType(String) contentType} header value to a compact {@code cty} IANA 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. This is a - * convenience method semantically equivalent to: + * Sets the JWT Claims + * sub (subject) value. A {@code null} value will remove the property from the Claims. * - *
-     * {@link #content(byte[]) content(content)}.{@link #header()}.{@link HeaderMutator#contentType(String) contentType(cty)}.{@link BuilderHeader#and() and()}
+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setSubject(String) subject} field with the specified value. This allows you to write + * code like this:

* - *

Compact Media Type Identifier

+ *
+     * String jwt = Jwts.builder().setSubject("Me").compact();
+     * 
* - *

This method will automatically remove any application/ prefix from the - * {@code cty} string if possible according to the rules defined in the last paragraph of - * RFC 7517, Section 4.1.10:

- *
-     *     To keep messages compact in common situations, it is RECOMMENDED that
-     *     producers omit an "application/" prefix of a media type value in a
-     *     "cty" Header Parameter when no other '/' appears in the media type
-     *     value.  A recipient using the media type value MUST treat it as if
-     *     "application/" were prepended to any "cty" value not containing a
-     *     '/'.  For instance, a "cty" value of "example" SHOULD be used to
-     *     represent the "application/example" media type, whereas the media
-     *     type "application/example;part="1/2"" cannot be shortened to
-     *     "example;part="1/2"".
+ *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setSubject("Me");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

* - *

JJWT performs the reverse during JWT parsing: {@link Header#getContentType()} will automatically prepend the - * {@code application/} prefix if the parsed {@code cty} value does not contain a '/' character (as - * mandated by the RFC language above). This ensures application developers can use and read standard IANA Media - * Type identifiers without needing JWT-specific prefix conditional logic in application code. - *

- * - *

Mutually Exclusive Claims and Content

- * - *

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. If you want the - * JWT payload to be JSON claims, use the {@link #claim(String, Object)} or {@link #claims()} methods instead.

- * - * @param content the content byte array that will be the JWT payload. Cannot be null or empty. - * @param cty the content type (media type) identifier attributed to the byte array. Cannot be null or empty. - * @return the builder for method chaining. - * @throws IllegalArgumentException if either {@code content} or {@code cty} are null or empty. - * @since 0.12.0 - */ - JwtBuilder content(byte[] content, String cty) throws IllegalArgumentException; - - /** - * Sets the JWT payload to be the specified content byte stream and also sets the - * {@link BuilderHeader#contentType(String) contentType} header value to a compact {@code cty} IANA 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. This is a - * convenience method semantically equivalent to: - * - *
-     * {@link #content(InputStream) content(content)}.{@link #header()}.{@link HeaderMutator#contentType(String) contentType(cty)}.{@link BuilderHeader#and() and()}
- * - *

Compact Media Type Identifier

- * - *

This method will automatically remove any application/ prefix from the - * {@code cty} string if possible according to the rules defined in the last paragraph of - * RFC 7517, Section 4.1.10:

- * - *
-     *     To keep messages compact in common situations, it is RECOMMENDED that
-     *     producers omit an "application/" prefix of a media type value in a
-     *     "cty" Header Parameter when no other '/' appears in the media type
-     *     value.  A recipient using the media type value MUST treat it as if
-     *     "application/" were prepended to any "cty" value not containing a
-     *     '/'.  For instance, a "cty" value of "example" SHOULD be used to
-     *     represent the "application/example" media type, whereas the media
-     *     type "application/example;part="1/2"" cannot be shortened to
-     *     "example;part="1/2"".
- * - *

JJWT performs the reverse during JWT parsing: {@link Header#getContentType()} will automatically prepend the - * {@code application/} prefix if the parsed {@code cty} value does not contain a '/' character (as - * mandated by the RFC language above). This ensures application developers can use and read standard IANA Media - * Type identifiers without needing JWT-specific prefix conditional logic in application code. - *

- * - *

Mutually Exclusive Claims and Content

- * - *

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. If you want the - * JWT payload to be JSON claims, use the {@link #claim(String, Object)} or {@link #claims()} methods instead.

- * - * @param content the content byte array that will be the JWT payload. Cannot be null. - * @param cty the content type (media type) identifier attributed to the byte array. Cannot be null or empty. - * @return the builder for method chaining. - * @throws IllegalArgumentException if either {@code content} or {@code cty} are null or empty. - * @since 0.12.0 - */ - JwtBuilder content(InputStream content, String cty) throws IllegalArgumentException; - - /** - * 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: - * - *
-     * String jwt = Jwts.builder()
-     *
-     *     .claims()
-     *         .issuer("me")
-     *         .subject("Joe")
-     *         .audience().add("you").and()
-     *         .add("customClaim", customValue)
-     *         .add(myClaimsMap)
-     *         // ... etc ...
-     *         .{@link BuilderClaims#and() and()} //return back to the JwtBuilder
-     *
-     *     .signWith(key) // resume JwtBuilder calls
-     *     // ... etc ...
-     *     .compact();
- * - * @return the {@link BuilderClaims} to use for Claims construction. - * @since 0.12.0 - */ - BuilderClaims claims(); - - /** - * Replaces the JWT Claims payload with the specified name/value pairs. This is an alias for: - *
-     * {@link #claims()}.{@link MapMutator#empty() empty()}.{@link MapMutator#add(Map) add(claims)}.{@link BuilderClaims#and() and()}
- * - *

The {@code content} and {@code claims} properties are mutually exclusive - only one of the two variants - * may be used.

- * - * @param claims the JWT Claims to be set as the JWT payload. - * @return the builder for method chaining. - * @see #claims() - * @see #content(String) - * @see #content(byte[]) - * @see #content(InputStream) - * @deprecated since 0.12.0 in favor of using the {@link #claims()} builder. - */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - JwtBuilder setClaims(Map claims); - - /** - * Adds/appends all given name/value pairs to the JSON Claims in the payload. This is an alias for: - * - *
-     * {@link #claims()}.{@link MapMutator#add(Map) add(claims)}.{@link BuilderClaims#and() and()}
- * - *

The content and claims properties are mutually exclusive - only one of the two may be used.

- * - * @param claims the JWT Claims to be added to the JWT payload. - * @return the builder for method chaining. - * @since 0.8 - * @deprecated since 0.12.0 in favor of - * {@link #claims()}.{@link BuilderClaims#add(Map) add(Map)}.{@link BuilderClaims#and() and()}. - * This method will be removed before the 1.0 release. - */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - JwtBuilder addClaims(Map claims); - - /** - * 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 alias for: - *
-     * {@link #claims()}.{@link MapMutator#add(Object, Object) add(name, value)}.{@link BuilderClaims#and() and()}
- * - * @param name the JWT Claims property name - * @param value the value to set for the specified Claims property name + * @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 */ - JwtBuilder claim(String name, Object value); + @Override + //only for better/targeted JavaDoc + JwtBuilder setSubject(String sub); /** - * 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 alias for: - *
-     * {@link #claims()}.{@link MapMutator#add(Map) add(claims)}.{@link BuilderClaims#and() and()}
+ * Sets the JWT Claims + * aud (audience) value. A {@code null} value will remove the property from the Claims. * - *

The content and claims properties are mutually exclusive - only one of the two may be used.

+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setAudience(String) audience} field with the specified value. This allows you to write + * code like this:

* - * @param claims the JWT Claims to be added to the JWT payload. - * @return the builder instance for method chaining - * @since 0.12.0 - */ - JwtBuilder claims(Map claims); - - /** - * Sets the JWT Claims - * iss (issuer) claim. A {@code null} value will remove the property from the Claims. - * This is a convenience wrapper for: - *
-     * {@link #claims()}.{@link ClaimsMutator#issuer(String) issuer(iss)}.{@link BuilderClaims#and() and()}
+ *
+     * String jwt = Jwts.builder().setAudience("You").compact();
+     * 
* - * @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 - * sub (subject) claim. A {@code null} value will remove the property from the Claims. - * This is a convenience wrapper for: - *
-     * {@link #claims()}.{@link ClaimsMutator#subject(String) subject(sub)}.{@link BuilderClaims#and() and()}
+ *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setAudience("You");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

* - * @param sub the JWT {@code sub} value or {@code null} to remove the property from the Claims map. + * @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 - // for better/targeted JavaDoc - JwtBuilder subject(String sub); + //only for better/targeted JavaDoc + JwtBuilder setAudience(String aud); /** - * Sets the JWT Claims - * exp (expiration) claim. A {@code null} value will remove the property from the Claims. + * Sets the JWT Claims + * exp (expiration) value. A {@code null} value will remove the property from the Claims. * *

A JWT obtained after this timestamp should not be used.

* - *

This is a convenience wrapper for:

- *
-     * {@link #claims()}.{@link ClaimsMutator#expiration(Date) expiration(exp)}.{@link BuilderClaims#and() and()}
+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setExpiration(java.util.Date) expiration} field with the specified value. This allows + * you to write code like this:

* + *
+     * String jwt = Jwts.builder().setExpiration(new Date(System.currentTimeMillis() + 3600000)).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setExpiration(new Date(System.currentTimeMillis() + 3600000));
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * * @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 - // for better/targeted JavaDoc - JwtBuilder expiration(Date exp); + //only for better/targeted JavaDoc + JwtBuilder setExpiration(Date exp); /** - * Sets the JWT Claims - * nbf (not before) claim. A {@code null} value will remove the property from the Claims. + * Sets the JWT Claims + * nbf (not before) value. A {@code null} value will remove the property from the Claims. * *

A JWT obtained before this timestamp should not be used.

* - *

This is a convenience wrapper for:

- *
-     * {@link #claims()}.{@link ClaimsMutator#notBefore(Date) notBefore(nbf)}.{@link BuilderClaims#and() and()}
+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setNotBefore(java.util.Date) notBefore} field with the specified value. This allows + * you to write code like this:

* + *
+     * String jwt = Jwts.builder().setNotBefore(new Date()).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setNotBefore(new Date());
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * * @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 - // for better/targeted JavaDoc - JwtBuilder notBefore(Date nbf); + //only for better/targeted JavaDoc + JwtBuilder setNotBefore(Date nbf); /** - * Sets the JWT Claims - * iat (issued at) claim. A {@code null} value will remove the property from the Claims. + * Sets the JWT Claims + * iat (issued at) value. A {@code null} value will remove the property from the Claims. * *

The value is the timestamp when the JWT was created.

* - *

This is a convenience wrapper for:

- *
-     * {@link #claims()}.{@link ClaimsMutator#issuedAt(Date) issuedAt(iat)}.{@link BuilderClaims#and() and()}
+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setIssuedAt(java.util.Date) issuedAt} field with the specified value. This allows + * you to write code like this:

* + *
+     * String jwt = Jwts.builder().setIssuedAt(new Date()).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setIssuedAt(new Date());
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * * @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 - // for better/targeted JavaDoc - JwtBuilder issuedAt(Date iat); + //only for better/targeted JavaDoc + JwtBuilder setIssuedAt(Date iat); /** - * Sets the JWT Claims - * jti (JWT ID) claim. A {@code null} value will remove the property from the Claims. + * Sets the JWT Claims + * jti (JWT ID) value. A {@code null} value will remove the property from the Claims. * *

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.

* - *

This is a convenience wrapper for:

- *
-     * {@link #claims()}.{@link ClaimsMutator#id(String) id(jti)}.{@link BuilderClaims#and() and()}
+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setId(String) id} field with the specified value. This allows + * you to write code like this:

* + *
+     * String jwt = Jwts.builder().setId(UUID.randomUUID().toString()).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setId(UUID.randomUUID().toString());
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * * @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 - // for better/targeted JavaDoc - JwtBuilder id(String jti); + //only for better/targeted JavaDoc + JwtBuilder setId(String jti); /** - * Signs the constructed JWT with the specified key using the key's recommended signature algorithm - * as defined below, producing a JWS. If the recommended signature algorithm isn't sufficient for your needs, - * consider using {@link #signWith(Key, SecureDigestAlgorithm)} instead. + * Sets a custom JWT Claims parameter value. A {@code null} value will remove the property from the Claims. * - *

If you are looking to invoke this method with a byte array that you are confident may be used for HMAC-SHA - * algorithms, consider using {@link Keys Keys}.{@link Keys#hmacShaKeyFor(byte[]) hmacShaKeyFor(bytes)} to - * convert the byte array into a valid {@code Key}.

+ *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body 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:

* - *

Recommended Signature Algorithm

+ *
+     * String jwt = Jwts.builder().claim("aName", "aValue").compact();
+     * 
* - *

The recommended signature algorithm used with a given key is chosen based on the following:

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Key Recommended Signature Algorithm
If the Key is a:And:With a key size of:The SignatureAlgorithm used will be:
{@link SecretKey}{@link Key#getAlgorithm() getAlgorithm()}.equals("HmacSHA256")1256 <= size <= 383 2{@link Jwts.SIG#HS256 HS256}
{@link SecretKey}{@link Key#getAlgorithm() getAlgorithm()}.equals("HmacSHA384")1384 <= size <= 511{@link Jwts.SIG#HS384 HS384}
{@link SecretKey}{@link Key#getAlgorithm() getAlgorithm()}.equals("HmacSHA512")1512 <= size{@link Jwts.SIG#HS512 HS512}
{@link ECKey}instanceof {@link PrivateKey}256 <= size <= 383 3{@link Jwts.SIG#ES256 ES256}
{@link ECKey}instanceof {@link PrivateKey}384 <= size <= 520 4{@link Jwts.SIG#ES384 ES384}
{@link ECKey}instanceof {@link PrivateKey}521 <= size 4{@link Jwts.SIG#ES512 ES512}
{@link RSAKey}instanceof {@link PrivateKey}2048 <= size <= 3071 5,6{@link Jwts.SIG#RS256 RS256}
{@link RSAKey}instanceof {@link PrivateKey}3072 <= size <= 4095 6{@link Jwts.SIG#RS384 RS384}
{@link RSAKey}instanceof {@link PrivateKey}4096 <= size 5{@link Jwts.SIG#RS512 RS512}
EdECKey7instanceof {@link PrivateKey}256 || 456{@link Jwts.SIG#EdDSA EdDSA}
- *

Notes:

- *
    - *
  1. {@code SecretKey} instances must have an {@link Key#getAlgorithm() algorithm} name equal - * to {@code HmacSHA256}, {@code HmacSHA384} or {@code HmacSHA512}. If not, the key bytes might not be - * suitable for HMAC signatures will be rejected with a {@link InvalidKeyException}.
  2. - *
  3. The JWT JWA Specification (RFC 7518, - * Section 3.2) mandates that HMAC-SHA-* signing keys MUST be 256 bits or greater. - * {@code SecretKey}s with key lengths less than 256 bits will be rejected with an - * {@link WeakKeyException}.
  4. - *
  5. The JWT JWA Specification (RFC 7518, - * Section 3.4) mandates that ECDSA signing key lengths MUST be 256 bits or greater. - * {@code ECKey}s with key lengths less than 256 bits will be rejected with a - * {@link WeakKeyException}.
  6. - *
  7. The ECDSA {@code P-521} curve does indeed use keys of 521 bits, not 512 as might be expected. ECDSA - * keys of 384 < size <= 520 are suitable for ES384, while ES512 requires keys >= 521 bits. The '512' part of the - * ES512 name reflects the usage of the SHA-512 algorithm, not the ECDSA key length. ES512 with ECDSA keys less - * than 521 bits will be rejected with a {@link WeakKeyException}.
  8. - *
  9. The JWT JWA Specification (RFC 7518, - * Section 3.3) mandates that RSA signing key lengths MUST be 2048 bits or greater. - * {@code RSAKey}s with key lengths less than 2048 bits will be rejected with a - * {@link WeakKeyException}.
  10. - *
  11. Technically any RSA key of length >= 2048 bits may be used with the - * {@link Jwts.SIG#RS256 RS256}, {@link Jwts.SIG#RS384 RS384}, and - * {@link Jwts.SIG#RS512 RS512} algorithms, so we assume an RSA signature algorithm based on the key - * length to parallel similar decisions in the JWT specification for HMAC and ECDSA signature algorithms. - * This is not required - just a convenience.
  12. - *
  13. EdECKeys - * require JDK >= 15 or BouncyCastle in the runtime classpath.
  14. - *
+ *

instead of this:

+ *
+     * Claims claims = Jwts.claims().put("aName", "aValue");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

* - *

This implementation does not use the {@link Jwts.SIG#PS256 PS256}, - * {@link Jwts.SIG#PS384 PS384}, or {@link Jwts.SIG#PS512 PS512} RSA variants for any - * specified {@link RSAKey} because the the {@link Jwts.SIG#RS256 RS256}, - * {@link Jwts.SIG#RS384 RS384}, and {@link Jwts.SIG#RS512 RS512} algorithms are - * available in the JDK by default while the {@code PS}* variants require either JDK 11 or an additional JCA - * Provider (like BouncyCastle). If you wish to use a {@code PS}* variant with your key, use the - * {@link #signWith(Key, SecureDigestAlgorithm)} method instead.

+ * @param name the JWT Claims property name + * @param value the value to set for the specified Claims property name + * @return the builder instance for method chaining. + * @since 0.2 + */ + JwtBuilder claim(String name, Object value); + + /** + * Signs the constructed JWT with the specified key using the key's + * {@link SignatureAlgorithm#forSigningKey(Key) recommended signature algorithm}, producing a JWS. If the + * recommended signature algorithm isn't sufficient for your needs, consider using + * {@link #signWith(Key, SignatureAlgorithm)} instead. * - *

Finally, this method will throw an {@link InvalidKeyException} for any key that does not match the - * heuristics and requirements documented above, since that inevitably means the Key is either insufficient, - * unsupported, or explicitly disallowed by the JWT specification.

+ *

If you are looking to invoke this method with a byte array that you are confident may be used for HMAC-SHA + * algorithms, consider using {@link Keys Keys}.{@link Keys#hmacShaKeyFor(byte[]) hmacShaKeyFor(bytes)} to + * convert the byte array into a valid {@code Key}.

* * @param key the key to use for signing * @return the builder instance for method chaining. - * @throws InvalidKeyException if the Key is insufficient, unsupported, or explicitly disallowed by the JWT - * specification as described above in recommended signature algorithms. - * @see Jwts.SIG - * @see #signWith(Key, SecureDigestAlgorithm) + * @throws InvalidKeyException if the Key is insufficient or explicitly disallowed by the JWT specification as + * described by {@link SignatureAlgorithm#forSigningKey(Key)}. + * @see #signWith(Key, SignatureAlgorithm) * @since 0.10.0 */ JwtBuilder signWith(Key key) throws InvalidKeyException; /** * Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS. * - *

Deprecation Notice: Deprecated as of 0.10.0

+ *

Deprecation Notice: Deprecated as of 0.10.0

* *

Use {@link Keys Keys}.{@link Keys#hmacShaKeyFor(byte[]) hmacShaKeyFor(bytes)} to - * obtain the {@code Key} and then invoke {@link #signWith(Key)} or - * {@link #signWith(Key, SecureDigestAlgorithm)}.

+ * obtain the {@code Key} and then invoke {@link #signWith(Key)} or {@link #signWith(Key, SignatureAlgorithm)}.

* *

This method will be removed in the 1.0 release.

* * @param alg the JWS algorithm to use to digitally sign the JWT, thereby producing a JWS. * @param secretKey the algorithm-specific signing key to use to digitally sign the JWT. * @return the builder for method chaining. - * @throws InvalidKeyException if the Key is insufficient for the specified algorithm or explicitly disallowed by - * the JWT specification. + * @throws InvalidKeyException if the Key is insufficient or explicitly disallowed by the JWT specification as + * described by {@link SignatureAlgorithm#forSigningKey(Key)}. * @deprecated as of 0.10.0: use {@link Keys Keys}.{@link Keys#hmacShaKeyFor(byte[]) hmacShaKeyFor(bytes)} to - * obtain the {@code Key} and then invoke {@link #signWith(Key)} or - * {@link #signWith(Key, SecureDigestAlgorithm)}. + * obtain the {@code Key} and then invoke {@link #signWith(Key)} or {@link #signWith(Key, SignatureAlgorithm)}. * This method will be removed in the 1.0 release. */ @Deprecated @@ -752,7 +390,7 @@ *

This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting * byte array is used to invoke {@link #signWith(SignatureAlgorithm, byte[])}.

* - *

Deprecation Notice: Deprecated as of 0.10.0, will be removed in the 1.0 release.

+ *

Deprecation Notice: Deprecated as of 0.10.0, will be removed in the 1.0 release.

* *

This method has been deprecated because the {@code key} argument for this method can be confusing: keys for * cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were @@ -764,20 +402,21 @@ *

{@code String base64EncodedSecretKey = base64Encode(secretKeyBytes);}

* *

However, a non-trivial number of JJWT users were confused by the method signature and attempted to - * use raw password strings as the key argument - for example {@code with(HS256, myPassword)} - which is + * use raw password strings as the key argument - for example {@code signWith(HS256, myPassword)} - which is * almost always incorrect for cryptographic hashes and can produce erroneous or insecure results.

* *

See this * * StackOverflow answer explaining why raw (non-base64-encoded) strings are almost always incorrect for * signature operations.

* - *

To perform the correct logic with base64EncodedSecretKey strings with JJWT >= 0.10.0, you may do this:

+ *

To perform the correct logic with base64EncodedSecretKey strings with JJWT >= 0.10.0, you may do this: *


      * byte[] keyBytes = {@link Decoders Decoders}.{@link Decoders#BASE64 BASE64}.{@link Decoder#decode(Object) decode(base64EncodedSecretKey)};
      * Key key = {@link Keys Keys}.{@link Keys#hmacShaKeyFor(byte[]) hmacShaKeyFor(keyBytes)};
-     * jwtBuilder.with(key); //or {@link #signWith(Key, SignatureAlgorithm)}
+     * jwtBuilder.signWith(key); //or {@link #signWith(Key, SignatureAlgorithm)}
      * 
+ *

* *

This method will be removed in the 1.0 release.

* @@ -806,22 +445,15 @@ * @throws InvalidKeyException if the Key is insufficient or explicitly disallowed by the JWT specification for * the specified algorithm. * @see #signWith(Key) - * @deprecated since 0.10.0. Use {@link #signWith(Key, SecureDigestAlgorithm)} instead. - * This method will be removed before the 1.0 release. + * @deprecated since 0.10.0: use {@link #signWith(Key, SignatureAlgorithm)} instead. This method will be removed + * in the 1.0 release. */ @Deprecated JwtBuilder signWith(SignatureAlgorithm alg, Key key) throws InvalidKeyException; /** - *

Deprecation Notice

+ * Signs the constructed JWT with the specified key using the specified algorithm, producing a JWS. * - *

This has been deprecated since 0.12.0. Use - * {@link #signWith(Key, SecureDigestAlgorithm)} instead. Standard JWA algorithms - * are represented as instances of this new interface in the {@link Jwts.SIG} - * algorithm registry.

- * - *

Signs the constructed JWT with the specified key using the specified algorithm, producing a JWS.

- * *

It is typically recommended to call the {@link #signWith(Key)} instead for simplicity. * However, this method can be useful if the recommended algorithm heuristics do not meet your needs or if * you want explicit control over the signature algorithm used with the specified key.

@@ -833,224 +465,66 @@ * the specified algorithm. * @see #signWith(Key) * @since 0.10.0 - * @deprecated since 0.12.0 to use the more flexible {@link #signWith(Key, SecureDigestAlgorithm)}. */ - @Deprecated JwtBuilder signWith(Key key, SignatureAlgorithm alg) throws InvalidKeyException; /** - * Signs the constructed JWT with the specified key using the specified algorithm, producing a JWS. + * Compresses the JWT body using the specified {@link CompressionCodec}. * - *

The {@link Jwts.SIG} registry makes available all standard signature - * algorithms defined in the JWA specification.

- * - *

It is typically recommended to call the {@link #signWith(Key)} instead for simplicity. - * However, this method can be useful if the recommended algorithm heuristics do not meet your needs or if - * you want explicit control over the signature algorithm used with the specified key.

- * - * @param key the signing key to use to digitally sign the JWT. - * @param The type of key accepted by the {@code SignatureAlgorithm}. - * @param alg the JWS algorithm to use with the key to digitally sign the JWT, thereby producing a JWS. - * @return the builder for method chaining. - * @throws InvalidKeyException if the Key is insufficient or explicitly disallowed by the JWT specification for - * the specified algorithm. - * @see #signWith(Key) - * @see Jwts.SIG - * @since 0.12.0 - */ - JwtBuilder signWith(K key, SecureDigestAlgorithm alg) throws InvalidKeyException; - - /** - * Encrypts the constructed JWT with the specified symmetric {@code key} using the provided {@code enc}ryption - * algorithm, producing a JWE. Because it is a symmetric key, the JWE recipient - * must also have access to the same key to decrypt. - * - *

This method is a convenience method that delegates to - * {@link #encryptWith(Key, KeyAlgorithm, AeadAlgorithm) encryptWith(Key, KeyAlgorithm, AeadAlgorithm)} - * based on the {@code key} argument:

- *
    - *
  • If the provided {@code key} is a {@link Password Password} instance, - * the {@code KeyAlgorithm} used will be one of the three JWA-standard password-based key algorithms - * ({@link Jwts.KEY#PBES2_HS256_A128KW PBES2_HS256_A128KW}, - * {@link Jwts.KEY#PBES2_HS384_A192KW PBES2_HS384_A192KW}, or - * {@link Jwts.KEY#PBES2_HS512_A256KW PBES2_HS512_A256KW}) as determined by the {@code enc} algorithm's - * {@link AeadAlgorithm#getKeyBitLength() key length} requirement.
  • - *
  • If the {@code key} is otherwise a standard {@code SecretKey}, the {@code KeyAlgorithm} will be - * {@link Jwts.KEY#DIRECT DIRECT}, indicating that {@code key} should be used directly with the - * {@code enc} algorithm. In this case, the {@code key} argument MUST 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#key() key()} builder.
  • - *
- * - * @param key the symmetric encryption key to use with the {@code enc} algorithm. - * @param enc the {@link AeadAlgorithm} algorithm used to encrypt the JWE, usually one of the JWA-standard - * algorithms accessible via {@link Jwts.ENC}. - * @return the JWE builder for method chaining. - * @see Jwts.ENC - */ - JwtBuilder encryptWith(SecretKey key, AeadAlgorithm enc); - - /** - * Encrypts the constructed JWT using the specified {@code enc} algorithm with the symmetric key produced by the - * {@code keyAlg} when invoked with the given {@code key}, producing a JWE. - * - *

This behavior can be illustrated by the following pseudocode, a rough example of what happens during - * {@link #compact() compact}ion:

- *
-     *     SecretKey encryptionKey = keyAlg.getEncryptionKey(key);           // (1)
-     *     byte[] jweCiphertext = enc.encrypt(payloadBytes, encryptionKey);  // (2)
- *
    - *
  1. The {@code keyAlg} argument is first invoked with the provided {@code key} argument, resulting in a - * {@link SecretKey}.
  2. - *
  3. This {@code SecretKey} result is used to call the provided {@code enc} encryption algorithm argument, - * resulting in the final JWE ciphertext.
  4. - *
- * - *

Most application developers will reference one of the JWA - * {@link Jwts.KEY standard key algorithms} and {@link Jwts.ENC standard encryption algorithms} - * when invoking this method, but custom implementations are also supported.

- * - * @param the type of key that must be used with the specified {@code keyAlg} instance. - * @param key the key used to invoke the provided {@code keyAlg} instance. - * @param keyAlg the key management algorithm that will produce the symmetric {@code SecretKey} to use with the - * {@code enc} algorithm - * @param enc the {@link AeadAlgorithm} algorithm used to encrypt the JWE - * @return the JWE builder for method chaining. - * @see Jwts.ENC - * @see Jwts.KEY - */ - JwtBuilder encryptWith(K key, KeyAlgorithm keyAlg, AeadAlgorithm enc); - - /** - * Compresses the JWT payload using the specified {@link CompressionAlgorithm}. - * *

If your compact JWTs are large, and you want to reduce their total size during network transmission, this * can be useful. For example, when embedding JWTs in URLs, some browsers may not support URLs longer than a * certain length. Using compression can help ensure the compact JWT fits within that length. However, NOTE:

* - *

Compatibility Warning

+ *

Compatibility Warning

* - *

The JWT family of specifications defines compression only for JWE (JSON Web Encryption) + *

The JWT family of specifications defines compression only for JWE (Json Web Encryption) * tokens. Even so, JJWT will also support compression for JWS tokens as well if you choose to use it. * However, be aware that if you use compression when creating a JWS token, other libraries may not be able to - * parse that JWS token. When using compression for JWS tokens, be sure that all parties accessing the + * parse that JWS token. When using compression for JWS tokens, be sure that that all parties accessing the * JWS token support compression for JWS.

* *

Compression when creating JWE tokens however should be universally accepted for any * library that supports JWE.

* - * @param alg implementation of the {@link CompressionAlgorithm} to be used. + * @param codec implementation of the {@link CompressionCodec} to be used. * @return the builder for method chaining. - * @see Jwts.ZIP - * @since 0.12.0 + * @see io.jsonwebtoken.CompressionCodecs + * @since 0.6.0 */ - JwtBuilder compressWith(CompressionAlgorithm alg); + JwtBuilder compressWith(CompressionCodec codec); /** - * Perform Base64Url encoding during {@link #compact() compaction} with the specified Encoder. + * Perform Base64Url encoding with the specified Encoder. * *

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.

* * @param base64UrlEncoder the encoder to use when Base64Url-encoding * @return the builder for method chaining. - * @see #b64Url(Encoder) * @since 0.10.0 - * @deprecated since 0.12.0 in favor of {@link #b64Url(Encoder)}. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated JwtBuilder base64UrlEncodeWith(Encoder base64UrlEncoder); /** - * Perform Base64Url encoding during {@link #compact() compaction} with the specified {@code OutputStream} Encoder. - * The Encoder's {@link Encoder#encode(Object) encode} method will be given a target {@code OutputStream} to - * wrap, and the resulting (wrapping) {@code OutputStream} will be used for writing, ensuring automatic - * Base64URL-encoding during write operations. + * Performs object-to-JSON serialization with the specified Serializer. This is used by the builder to convert + * JWT/JWS/JWT headers and claims Maps to JSON strings as required by the JWT specification. * - *

JJWT uses a spec-compliant encoder that works on all supported JDK versions, but you may call this method - * to specify a different stream encoder if desired.

- * - * @param encoder the encoder to use when Base64Url-encoding - * @return the builder for method chaining. - * @since 0.12.0 - */ - JwtBuilder b64Url(Encoder encoder); - - /** - * Enables RFC 7797: JSON Web Signature (JWS) - * Unencoded Payload Option if {@code false}, or standard JWT/JWS/JWE payload encoding otherwise. The default - * value is {@code true} per standard RFC behavior rules. - * - *

This value may only be {@code false} for JWSs (signed JWTs). It may not be used for standard - * (unprotected) JWTs or encrypted JWTs (JWEs). The builder will throw an exception during {@link #compact()} if - * {@code false} and a JWS is not being created.

- * - * @param b64 whether to Base64URL-encode the JWS payload - * @return the builder for method chaining. - */ - JwtBuilder encodePayload(boolean b64); - - /** - * 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. - * *

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.

* * @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 0.12.0 in favor of {@link #json(Serializer)} */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated JwtBuilder serializeToJsonWith(Serializer> 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. - * - *

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.

- * - * @param serializer the Serializer to use when converting Map objects to JSON strings. - * @return the builder for method chaining. - * @since 0.12.0 - */ - JwtBuilder json(Serializer> serializer); - - /** * Actually builds the JWT and serializes it to a compact, URL-safe string according to the - * JWT Compact Serialization + * JWT Compact Serialization * rules. * * @return A compact URL-safe JWT string. */ String compact(); - - /** - * 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 0.12.0 - */ - interface BuilderClaims extends MapMutator, ClaimsMutator, - Conjunctor { - } - - /** - * 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 0.12.0 - */ - interface BuilderHeader extends JweHeaderMutator, X509Builder, - Conjunctor { - } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtException.java (.../JwtException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtException.java (.../JwtException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,21 +22,10 @@ */ public class JwtException extends RuntimeException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public JwtException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public JwtException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtHandler.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtHandler.java (.../JwtHandler.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtHandler.java (.../JwtHandler.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,31 +17,25 @@ /** * A JwtHandler is invoked by a {@link io.jsonwebtoken.JwtParser JwtParser} after parsing a JWT to indicate the exact - * type of JWT, JWS or JWE parsed. + * type of JWT or JWS parsed. * * @param the type of object to return to the parser caller after handling the parsed JWT. * @since 0.2 - * @deprecated since 0.12.0 in favor of calling {@link Jwt#accept(JwtVisitor)}. */ -@SuppressWarnings("DeprecatedIsStillUsed") -@Deprecated -public interface JwtHandler extends JwtVisitor { +public interface JwtHandler { /** * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is - * an unsecured content JWT. An unsecured content JWT has a byte array payload that is not - * cryptographically signed or encrypted. If the JWT creator set the (optional) - * {@link Header#getContentType() contentType} header value, the application may inspect that value to determine - * how to convert the byte array to the final content type as desired. + * a plaintext JWT. A plaintext JWT has a String (non-JSON) body payload and it is not cryptographically signed. * - * @param jwt the parsed unsecured content JWT + * @param jwt the parsed plaintext JWT * @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary. */ - T onContentJwt(Jwt jwt); + T onPlaintextJwt(Jwt jwt); /** * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is - * a Claims JWT. A Claims JWT has a {@link Claims} payload that is not cryptographically signed or encrypted. + * a Claims JWT. A Claims JWT has a {@link Claims} body and it is not cryptographically signed. * * @param jwt the parsed claims JWT * @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary. @@ -50,21 +44,19 @@ /** * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is - * a content JWS. A content JWS is a JWT with a byte array payload that has been cryptographically signed. - * If the JWT creator set the (optional) {@link Header#getContentType() contentType} header value, the - * application may inspect that value to determine how to convert the byte array to the final content type - * as desired. + * a plaintext JWS. A plaintext JWS is a JWT with a String (non-JSON) body (payload) that has been + * cryptographically signed. * *

This method will only be invoked if the cryptographic signature can be successfully verified.

* - * @param jws the parsed content JWS + * @param jws the parsed plaintext JWS * @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary. */ - T onContentJws(Jws jws); + T onPlaintextJws(Jws jws); /** * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is - * a valid Claims JWS. A Claims JWS is a JWT with a {@link Claims} payload that has been cryptographically signed. + * a valid Claims JWS. A Claims JWS is a JWT with a {@link Claims} body that has been cryptographically signed. * *

This method will only be invoked if the cryptographic signature can be successfully verified.

* @@ -73,30 +65,4 @@ */ T onClaimsJws(Jws jws); - /** - * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is - * a content JWE. A content JWE is a JWE with a byte array payload that has been encrypted. If the JWT creator set - * the (optional) {@link Header#getContentType() contentType} header value, the application may inspect that - * value to determine how to convert the byte array to the final content type as desired. - * - *

This method will only be invoked if the content JWE can be successfully decrypted.

- * - * @param jwe the parsed content jwe - * @return any object to be used after inspecting the JWE, or {@code null} if no return value is necessary. - * @since 0.12.0 - */ - T onContentJwe(Jwe jwe); - - /** - * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is - * a valid Claims JWE. A Claims JWE is a JWT with a {@link Claims} payload that has been encrypted. - * - *

This method will only be invoked if the Claims JWE can be successfully decrypted.

- * - * @param jwe the parsed claims jwe - * @return any object to be used after inspecting the JWE, or {@code null} if no return value is necessary. - * @since 0.12.0 - */ - T onClaimsJwe(Jwe jwe); - } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtHandlerAdapter.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtHandlerAdapter.java (.../JwtHandlerAdapter.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtHandlerAdapter.java (.../JwtHandlerAdapter.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -21,78 +21,32 @@ * known/expected for a particular use case. * *

All of the methods in this implementation throw exceptions: overridden methods represent - * scenarios expected by calling code in known situations. It would be unexpected to receive a JWT that did + * scenarios expected by calling code in known situations. It would be unexpected to receive a JWS or JWT that did * not match parsing expectations, so all non-overridden methods throw exceptions to indicate that the JWT * input was unexpected.

* * @param the type of object to return to the parser caller after handling the parsed JWT. * @since 0.2 */ -public abstract class JwtHandlerAdapter extends SupportedJwtVisitor implements JwtHandler { +public class JwtHandlerAdapter implements JwtHandler { - /** - * Default constructor, does not initialize any internal state. - */ - public JwtHandlerAdapter() { - } - @Override - public T onUnsecuredContent(Jwt jwt) { - return onContentJwt(jwt); // bridge for existing implementations + public T onPlaintextJwt(Jwt jwt) { + throw new UnsupportedJwtException("Unsigned plaintext JWTs are not supported."); } @Override - public T onUnsecuredClaims(Jwt jwt) { - return onClaimsJwt(jwt); - } - - @Override - public T onVerifiedContent(Jws jws) { - return onContentJws(jws); - } - - @Override - public T onVerifiedClaims(Jws jws) { - return onClaimsJws(jws); - } - - @Override - public T onDecryptedContent(Jwe jwe) { - return onContentJwe(jwe); - } - - @Override - public T onDecryptedClaims(Jwe jwe) { - return onClaimsJwe(jwe); - } - - @Override - public T onContentJwt(Jwt jwt) { - return super.onUnsecuredContent(jwt); - } - - @Override public T onClaimsJwt(Jwt jwt) { - return super.onUnsecuredClaims(jwt); + throw new UnsupportedJwtException("Unsigned Claims JWTs are not supported."); } @Override - public T onContentJws(Jws jws) { - return super.onVerifiedContent(jws); + public T onPlaintextJws(Jws jws) { + throw new UnsupportedJwtException("Signed plaintext JWSs are not supported."); } @Override public T onClaimsJws(Jws jws) { - return super.onVerifiedClaims(jws); + throw new UnsupportedJwtException("Signed Claims JWSs are not supported."); } - - @Override - public T onContentJwe(Jwe jwe) { - return super.onDecryptedContent(jwe); - } - - @Override - public T onClaimsJwe(Jwe jwe) { - return super.onDecryptedClaims(jwe); - } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtParser.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtParser.java (.../JwtParser.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtParser.java (.../JwtParser.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,408 +15,582 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.io.Parser; -import io.jsonwebtoken.security.SecurityException; +import io.jsonwebtoken.io.Decoder; +import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.security.SignatureException; -import java.io.InputStream; +import java.security.Key; +import java.util.Date; +import java.util.Map; /** * A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT. - * A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT. * * @since 0.1 */ -public interface JwtParser extends Parser> { +public interface JwtParser { + public static final char SEPARATOR_CHAR = '.'; + /** - * Returns {@code true} if the specified JWT compact string represents a signed JWT (aka a 'JWS'), {@code false} - * otherwise. + * Ensures that the specified {@code jti} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

Note that if you are reasonably sure that the token is signed, it is more efficient to attempt to - * parse the token (and catching exceptions if necessary) instead of calling this method first before parsing.

- * - * @param compact the compact serialized JWT to check - * @return {@code true} if the specified JWT compact string represents a signed JWT (aka a 'JWS'), {@code false} - * otherwise. + * @param id + * @return the parser method for chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireId(String)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - boolean isSigned(CharSequence compact); + @Deprecated + JwtParser requireId(String id); /** - * Parses the specified compact serialized JWT string based on the builder's current configuration state and - * returns the resulting JWT, JWS, or JWE instance. + * Ensures that the specified {@code sub} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

Because it is often cumbersome to determine if the result is a JWT, JWS or JWE, or if the payload is a Claims - * or {@code byte[]} array with {@code instanceof} checks, it may be useful to call the result's - * {@link Jwt#accept(JwtVisitor) accept(JwtVisitor)} method for a type-safe callback approach instead of using if-then-else - * {@code instanceof} conditionals. For example, instead of:

- * - *
-     * // NOT RECOMMENDED:
-     * Jwt<?,?> jwt = parser.parse(input);
-     * if (jwt instanceof Jwe<?>) {
-     *     Jwe<?> jwe = (Jwe<?>)jwt;
-     *     if (jwe.getPayload() instanceof Claims) {
-     *         Jwe<Claims> claimsJwe = (Jwe<Claims>)jwe;
-     *         // do something with claimsJwe
-     *     }
-     * }
- * - *

the following alternative is usually preferred:

- * - *
-     * Jwe<Claims> jwe = parser.parse(input).accept({@link Jwe#CLAIMS});
- * - * @param jwt the compact serialized JWT to parse - * @return the parsed JWT instance - * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). - * Invalid JWTs should not be trusted and should be discarded. - * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail - * signature validation should not be trusted and should be discarded. - * @throws SecurityException if the specified JWT string is a JWE and decryption fails - * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time - * before the time this method is invoked. - * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace. - * @see Jwt#accept(JwtVisitor) + * @param subject + * @return the parser for method chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireSubject(String)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jwt parse(CharSequence jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException, - SecurityException, IllegalArgumentException; + @Deprecated + JwtParser requireSubject(String subject); /** - * Deprecated since 0.12.0 in favor of calling any {@code parse*} method immediately - * followed by invoking the parsed JWT's {@link Jwt#accept(JwtVisitor) accept} method with your preferred visitor. For - * example: + * Ensures that the specified {@code aud} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

-     * {@link #parse(CharSequence) parse}(jwt).{@link Jwt#accept(JwtVisitor) accept}({@link JwtVisitor visitor});
- * - *

This method will be removed before the 1.0 release.

- * - * @param jwt the compact serialized JWT to parse - * @param handler the handler to invoke when encountering a specific type of JWT - * @param the type of object returned from the {@code handler} - * @return the result returned by the {@code JwtHandler} - * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). - * Invalid JWTs should not be trusted and should be discarded. - * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail - * signature validation should not be trusted and should be discarded. - * @throws SecurityException if the specified JWT string is a JWE and decryption fails - * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time - * before the time this method is invoked. - * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace, or if the - * {@code handler} is {@code null}. - * @see Jwt#accept(JwtVisitor) - * @since 0.2 - * @deprecated since 0.12.0 in favor of - * {@link #parse(CharSequence)}.{@link Jwt#accept(JwtVisitor) accept}({@link JwtVisitor visitor}); + * @param audience + * @return the parser for method chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireAudience(String)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ @Deprecated - T parse(CharSequence jwt, JwtHandler handler) throws ExpiredJwtException, UnsupportedJwtException, - MalformedJwtException, SignatureException, SecurityException, IllegalArgumentException; + JwtParser requireAudience(String audience); /** - * Deprecated since 0.12.0 in favor of {@link #parseUnsecuredContent(CharSequence)}. + * Ensures that the specified {@code iss} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

This method will be removed before the 1.0 release.

- * - * @param jwt a compact serialized unsecured content JWT string. - * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. - * @throws UnsupportedJwtException if the {@code jwt} argument does not represent an unsecured content JWT - * @throws MalformedJwtException if the {@code jwt} string is not a valid JWT - * @throws SignatureException if the {@code jwt} string is actually a JWS and signature validation fails - * @throws SecurityException if the {@code jwt} string is actually a JWE and decryption fails - * @throws IllegalArgumentException if the {@code jwt} string is {@code null} or empty or only whitespace - * @see #parseUnsecuredContent(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.2 - * @deprecated since 0.12.0 in favor of {@link #parseUnsecuredContent(CharSequence)}. + * @param issuer + * @return the parser for method chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireIssuer(String)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated - Jwt parseContentJwt(CharSequence jwt) throws UnsupportedJwtException, MalformedJwtException, - SignatureException, SecurityException, IllegalArgumentException; + JwtParser requireIssuer(String issuer); /** - * Deprecated since 0.12.0 in favor of {@link #parseUnsecuredClaims(CharSequence)}. + * Ensures that the specified {@code iat} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

This method will be removed before the 1.0 release.

- * - * @param jwt a compact serialized unsecured Claims JWT string. - * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. - * @throws UnsupportedJwtException if the {@code jwt} argument does not represent an unsecured Claims JWT - * @throws MalformedJwtException if the {@code jwt} string is not a valid JWT - * @throws SignatureException if the {@code jwt} string is actually a JWS and signature validation fails - * @throws SecurityException if the {@code jwt} string is actually a JWE and decryption fails - * @throws IllegalArgumentException if the {@code jwt} string is {@code null} or empty or only whitespace - * @see #parseUnsecuredClaims(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.2 - * @deprecated since 0.12.0 in favor of {@link #parseUnsecuredClaims(CharSequence)}. + * @param issuedAt + * @return the parser for method chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireIssuedAt(Date)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated - Jwt parseClaimsJwt(CharSequence jwt) throws ExpiredJwtException, UnsupportedJwtException, - MalformedJwtException, SignatureException, SecurityException, IllegalArgumentException; + JwtParser requireIssuedAt(Date issuedAt); /** - * Deprecated since 0.12.0 in favor of {@link #parseSignedContent(CharSequence)}. + * Ensures that the specified {@code exp} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

This method will be removed before the 1.0 release.

- * - * @param jws a compact content JWS string - * @return the parsed and validated content JWS - * @throws UnsupportedJwtException if the {@code jws} argument does not represent a content JWS - * @throws MalformedJwtException if the {@code jws} string is not a valid JWS - * @throws SignatureException if the {@code jws} JWS signature validation fails - * @throws SecurityException if the {@code jws} string is actually a JWE and decryption fails - * @throws IllegalArgumentException if the {@code jws} string is {@code null} or empty or only whitespace - * @see #parseSignedContent(CharSequence) - * @see #parseEncryptedContent(CharSequence) - * @see #parse(CharSequence) - * @since 0.2 - * @deprecated since 0.12.0 in favor of {@link #parseSignedContent(CharSequence)}. + * @param expiration + * @return the parser for method chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireExpiration(Date)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated - Jws parseContentJws(CharSequence jws) throws UnsupportedJwtException, MalformedJwtException, SignatureException, - SecurityException, IllegalArgumentException; + JwtParser requireExpiration(Date expiration); /** - * Deprecated since 0.12.0 in favor of {@link #parseSignedClaims(CharSequence)}. + * Ensures that the specified {@code nbf} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - * @param jws a compact Claims JWS string. - * @return the parsed and validated Claims JWS - * @throws UnsupportedJwtException if the {@code claimsJws} argument does not represent an Claims JWS - * @throws MalformedJwtException if the {@code claimsJws} string is not a valid JWS - * @throws SignatureException if the {@code claimsJws} JWS signature validation fails - * @throws SecurityException if the {@code jws} string is actually a JWE and decryption fails - * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time - * before the time this method is invoked. - * @throws IllegalArgumentException if the {@code claimsJws} string is {@code null} or empty or only whitespace - * @see #parseSignedClaims(CharSequence) - * @see #parseEncryptedClaims(CharSequence) - * @see #parse(CharSequence) - * @since 0.2 - * @deprecated since 0.12.0 in favor of {@link #parseSignedClaims(CharSequence)}. + * @param notBefore + * @return the parser for method chaining + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#requireNotBefore(Date)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated - Jws parseClaimsJws(CharSequence jws) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, - SignatureException, SecurityException, IllegalArgumentException; + JwtParser requireNotBefore(Date notBefore); /** - * Parses the {@code jwt} argument, expected to be an unsecured content JWT. If the JWT creator set - * the (optional) {@link Header#getContentType() contentType} header value, the application may inspect that - * value to determine how to convert the byte array to the final content type as desired. + * Ensures that the specified {@code claimName} exists in the parsed JWT. If missing or if the parsed + * value does not equal the specified value, an exception will be thrown indicating that the + * JWT is invalid and may not be used. * - *

This is a convenience method logically equivalent to the following:

- * - *
-     * {@link #parse(CharSequence) parse}(jwt).{@link Jwt#accept(JwtVisitor) accept}({@link
-     * Jwt#UNSECURED_CONTENT});
- * - * @param jwt a compact unsecured content JWT. - * @return the parsed unsecured content JWT. - * @throws UnsupportedJwtException if the {@code jwt} argument does not represent an unsecured content JWT - * @throws JwtException if the {@code jwt} string cannot be parsed or validated as required. - * @throws IllegalArgumentException if the {@code jwt} string is {@code null} or empty or only whitespace - * @see #parse(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.12.0 + * @param claimName + * @param value + * @return the parser for method chaining. + * @see MissingClaimException + * @see IncorrectClaimException + * @deprecated see {@link JwtParserBuilder#require(String, Object)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jwt parseUnsecuredContent(CharSequence jwt) throws JwtException, IllegalArgumentException; + @Deprecated + JwtParser require(String claimName, Object value); /** - * Parses the {@code jwt} argument, expected to be an unsecured {@code Claims} JWT. This is a - * convenience method logically equivalent to the following: + * 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. * - *

-     * {@link #parse(CharSequence) parse}(jwt).{@link Jwt#accept(JwtVisitor) accept}({@link
-     * Jwt#UNSECURED_CLAIMS});
- * - * @param jwt a compact unsecured Claims JWT. - * @return the parsed unsecured Claims JWT. - * @throws UnsupportedJwtException if the {@code jwt} argument does not represent an unsecured Claims JWT - * @throws JwtException if the {@code jwt} string cannot be parsed or validated as required. - * @throws IllegalArgumentException if the {@code jwt} string is {@code null} or empty or only whitespace - * @see #parse(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.12.0 + * @param clock a {@code Clock} object to return the timestamp to use when validating the parsed JWT. + * @return the parser for method chaining. + * @since 0.7.0 + * @deprecated see {@link JwtParserBuilder#setClock(Clock)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jwt parseUnsecuredClaims(CharSequence jwt) throws JwtException, IllegalArgumentException; + @Deprecated + JwtParser setClock(Clock clock); /** - * Parses the {@code jws} argument, expected to be a cryptographically-signed content JWS. If the JWS - * creator set the (optional) {@link Header#getContentType() contentType} header value, the application may - * inspect that value to determine how to convert the byte array to the final content type as desired. + * Sets the amount of clock skew in seconds to tolerate when verifying the local time against the {@code exp} + * and {@code nbf} claims. * - *

This is a convenience method logically equivalent to the following:

- * - *
-     * {@link #parse(CharSequence) parse}(jws).{@link Jwt#accept(JwtVisitor) accept}({@link
-     * Jws#CONTENT});
- * - * @param jws a compact cryptographically-signed content JWS. - * @return the parsed cryptographically-verified content JWS. - * @throws UnsupportedJwtException if the {@code jws} argument does not represent a signed content JWS - * @throws JwtException if the {@code jws} string cannot be parsed or validated as required. - * @throws IllegalArgumentException if the {@code jws} string is {@code null} or empty or only whitespace - * @see #parse(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.12.0 + * @param seconds the number of seconds to tolerate for clock skew when verifying {@code exp} or {@code nbf} claims. + * @return the parser for method chaining. + * @since 0.7.0 + * @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 see {@link JwtParserBuilder#setAllowedClockSkewSeconds(long)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jws parseSignedContent(CharSequence jws) throws JwtException, IllegalArgumentException; + @Deprecated + JwtParser setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException; /** - * Parses a JWS known to use the - * RFC 7797: JSON Web Signature (JWS) Unencoded Payload - * Option, using the specified {@code unencodedPayload} for signature verification. + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

+ *

Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

+ *

+ *

This method overwrites any previously set key.

* - *

Unencoded Non-Detached Payload

- * - *

Note that if the JWS contains a valid unencoded Payload string (what RFC 7797 calls an - * "unencoded non-detached - * payload", the {@code unencodedPayload} method argument will be ignored, as the JWS already includes - * the payload content necessary for signature verification.

- * - * @param jws the Unencoded Payload JWS to parse. - * @param unencodedPayload the JWS's associated required unencoded payload used for signature verification. - * @return the parsed Unencoded Payload. - * @since 0.12.0 + * @param key the algorithm-specific signature verification key used to validate any discovered JWS digital + * signature. + * @return the parser for method chaining. + * @deprecated see {@link JwtParserBuilder#setSigningKey(byte[])}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jws parseSignedContent(CharSequence jws, byte[] unencodedPayload); + @Deprecated + JwtParser setSigningKey(byte[] key); /** - * Parses a JWS known to use the - * RFC 7797: JSON Web Signature (JWS) Unencoded Payload - * Option, using the bytes from the specified {@code unencodedPayload} stream for signature verification. + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. * - *

Because it is not possible to know how large the {@code unencodedPayload} stream will be, the stream bytes - * will not be buffered in memory, ensuring the resulting {@link Jws} return value's {@link Jws#getPayload()} - * is always empty. This is generally not a concern since the caller already has access to the stream bytes and - * may obtain them independently before or after calling this method if they are needed otherwise.

+ *

Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

* - *

Unencoded Non-Detached Payload

+ *

This method overwrites any previously set key.

* - *

Note that if the JWS contains a valid unencoded payload String (what RFC 7797 calls an - * "unencoded non-detached - * payload", the {@code unencodedPayload} method argument will be ignored, as the JWS already includes - * the payload content necessary for signature verification. In this case the resulting {@link Jws} return - * value's {@link Jws#getPayload()} will contain the embedded payload String's UTF-8 bytes.

+ *

This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting + * byte array is used to invoke {@link #setSigningKey(byte[])}.

* - * @param jws the Unencoded Payload JWS to parse. - * @param unencodedPayload the JWS's associated required unencoded payload used for signature verification. - * @return the parsed Unencoded Payload. - * @since 0.12.0 + *

Deprecation Notice: Deprecated as of 0.10.0, will be removed in 1.0.0

+ * + *

This method has been deprecated because the {@code key} argument for this method can be confusing: keys for + * cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were + * obtained from the String argument.

+ * + *

This method always expected a String argument that was effectively the same as the result of the following + * (pseudocode):

+ * + *

{@code String base64EncodedSecretKey = base64Encode(secretKeyBytes);}

+ * + *

However, a non-trivial number of JJWT users were confused by the method signature and attempted to + * use raw password strings as the key argument - for example {@code setSigningKey(myPassword)} - which is + * almost always incorrect for cryptographic hashes and can produce erroneous or insecure results.

+ * + *

See this + * + * StackOverflow answer explaining why raw (non-base64-encoded) strings are almost always incorrect for + * signature operations.

+ * + *

Finally, please use the {@link #setSigningKey(Key) setSigningKey(Key)} instead, as this method and the + * {@code byte[]} variant will be removed before the 1.0.0 release.

+ * + * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signature verification key to use to validate + * any discovered JWS digital signature. + * @return the parser for method chaining. + * @deprecated see {@link JwtParserBuilder#setSigningKey(String)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jws parseSignedContent(CharSequence jws, InputStream unencodedPayload); + @Deprecated + JwtParser setSigningKey(String base64EncodedSecretKey); /** - * Parses the {@code jws} argument, expected to be a cryptographically-signed {@code Claims} JWS. This is a - * convenience method logically equivalent to the following: + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

+ *

Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

+ *

+ *

This method overwrites any previously set key.

* - *
-     * {@link #parse(CharSequence) parse}(jws).{@link Jwt#accept(JwtVisitor) accept}({@link
-     * Jws#CLAIMS});
+ * @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital + * signature. + * @return the parser for method chaining. + * @deprecated see {@link JwtParserBuilder#setSigningKey(Key)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser setSigningKey(Key key); + + /** + * Sets the {@link SigningKeyResolver} used to acquire the signing key that should be used to verify + * a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used. + *

+ *

Specifying a {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing + * the JWT and the JWT header or payload (plaintext body or Claims) must be inspected first to determine how to + * look up the signing key. Once returned by the resolver, the JwtParser will then verify the JWS signature with the + * returned key. For example:

+ *

+ *

+     * Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
+     *         @Override
+     *         public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
+     *             //inspect the header or claims, lookup and return the signing key
+     *             return getSigningKey(header, claims); //implement me
+     *         }})
+     *     .parseClaimsJws(compact);
+     * 
+ *

+ *

A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.

+ *

+ *

This method should only be used if a signing key is not provided by the other {@code setSigningKey*} builder + * methods.

* - * @param jws a compact cryptographically-signed Claims JWS. - * @return the parsed cryptographically-verified Claims JWS. - * @throws UnsupportedJwtException if the {@code jwt} argument does not represent a signed Claims JWT - * @throws JwtException if the {@code jwt} string cannot be parsed or validated as required. - * @throws IllegalArgumentException if the {@code jwt} string is {@code null} or empty or only whitespace - * @see #parse(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.12.0 + * @param signingKeyResolver the signing key resolver used to retrieve the signing key. + * @return the parser for method chaining. + * @since 0.4 + * @deprecated see {@link JwtParserBuilder#setSigningKeyResolver(SigningKeyResolver)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jws parseSignedClaims(CharSequence jws) throws JwtException, IllegalArgumentException; + @Deprecated + JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver); /** - * Parses a JWS known to use the - * RFC 7797: JSON Web Signature (JWS) Unencoded Payload - * Option, using the specified {@code unencodedPayload} for signature verification. + * Sets the {@link CompressionCodecResolver} used to acquire the {@link CompressionCodec} that should be used to + * decompress the JWT body. If the parsed JWT is not compressed, this resolver is not used. + *

NOTE: Compression is not defined by the JWT Specification, and it is not expected that other libraries + * (including JJWT versions < 0.6.0) are able to consume a compressed JWT body correctly. This method is only + * useful if the compact JWT was compressed with JJWT >= 0.6.0 or another library that you know implements + * the same behavior.

+ *

Default Support

+ *

JJWT's default {@link JwtParser} implementation supports both the + * {@link CompressionCodecs#DEFLATE DEFLATE} + * and {@link CompressionCodecs#GZIP GZIP} algorithms by default - you do not need to + * specify a {@code CompressionCodecResolver} in these cases.

+ *

However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you must implement + * your own {@link CompressionCodecResolver} and specify that via this method and also when + * {@link io.jsonwebtoken.JwtBuilder#compressWith(CompressionCodec) building} JWTs.

* - *

Unencoded Non-Detached Payload

+ * @param compressionCodecResolver the compression codec resolver used to decompress the JWT body. + * @return the parser for method chaining. + * @since 0.6.0 + * @deprecated see {@link JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver); + + /** + * Perform Base64Url decoding with the specified Decoder * - *

Note that if the JWS contains a valid unencoded payload String (what RFC 7797 calls an - * "unencoded non-detached - * payload", the {@code unencodedPayload} method argument will be ignored, as the JWS already includes - * the payload content necessary for signature verification and claims creation.

+ *

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.

* - * @param jws the Unencoded Payload JWS to parse. - * @param unencodedPayload the JWS's associated required unencoded payload used for signature verification. - * @return the parsed and validated Claims JWS. - * @throws JwtException if parsing, signature verification, or JWT validation fails. - * @throws IllegalArgumentException if either the {@code jws} or {@code unencodedPayload} are null or empty. - * @since 0.12.0 + * @param base64UrlDecoder the decoder to use when Base64Url-decoding + * @return the parser for method chaining. + * @since 0.10.0 + * @deprecated see {@link JwtParserBuilder#base64UrlDecodeWith(Decoder)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 */ - Jws parseSignedClaims(CharSequence jws, byte[] unencodedPayload) throws JwtException, IllegalArgumentException; + @Deprecated + JwtParser base64UrlDecodeWith(Decoder base64UrlDecoder); /** - * Parses a JWS known to use the - * RFC 7797: JSON Web Signature (JWS) Unencoded Payload - * Option, using the bytes from the specified {@code unencodedPayload} stream for signature verification and - * {@link Claims} creation. + * 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. * - *

NOTE: however, because calling this method indicates a completed - * {@link Claims} instance is desired, the specified {@code unencodedPayload} JSON stream will be fully - * read into a Claims instance. If this will be problematic for your application (perhaps if you expect extremely - * large Claims), it is recommended to use the {@link #parseSignedContent(CharSequence, InputStream)} method - * instead.

+ *

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.

* - *

Unencoded Non-Detached Payload

+ * @param deserializer the deserializer to use when converting JSON Strings (UTF-8 byte arrays) into Map objects. + * @return the parser for method chaining. + * @since 0.10.0 + * @deprecated see {@link JwtParserBuilder#deserializeJsonWith(Deserializer)} )}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser deserializeJsonWith(Deserializer> deserializer); + + /** + * Returns {@code true} if the specified JWT compact string represents a signed JWT (aka a 'JWS'), {@code false} + * otherwise. + *

+ *

Note that if you are reasonably sure that the token is signed, it is more efficient to attempt to + * parse the token (and catching exceptions if necessary) instead of calling this method first before parsing.

* - *

Note that if the JWS contains a valid unencoded Payload string (what RFC 7797 calls an - * "unencoded non-detached - * payload", the {@code unencodedPayload} method argument will be ignored, as the JWS already includes - * the payload content necessary for signature verification and Claims creation.

+ * @param jwt the compact serialized JWT to check + * @return {@code true} if the specified JWT compact string represents a signed JWT (aka a 'JWS'), {@code false} + * otherwise. + */ + boolean isSigned(String jwt); + + /** + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * returns the resulting JWT or JWS instance. + *

+ *

This method returns a JWT or JWS based on the parsed string. Because it may be cumbersome to determine if it + * is a JWT or JWS, or if the body/payload is a Claims or String with {@code instanceof} checks, the + * {@link #parse(String, JwtHandler) parse(String,JwtHandler)} method allows for a type-safe callback approach that + * may help reduce code or instanceof checks.

* - * @param jws the Unencoded Payload JWS to parse. - * @param unencodedPayload the JWS's associated required unencoded payload used for signature verification. - * @return the parsed and validated Claims JWS. - * @throws JwtException if parsing, signature verification, or JWT validation fails. - * @throws IllegalArgumentException if either the {@code jws} or {@code unencodedPayload} are null or empty. - * @since 0.12.0 + * @param jwt the compact serialized JWT to parse + * @return the specified compact serialized JWT string based on the builder's current configuration state. + * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). + * Invalid + * JWTs should not be trusted and should be discarded. + * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail + * signature validation should not be trusted and should be discarded. + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace. + * @see #parse(String, JwtHandler) + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) */ - Jws parseSignedClaims(CharSequence jws, InputStream unencodedPayload) throws JwtException, IllegalArgumentException; + Jwt parse(String jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; /** - * Parses the {@code jwe} argument, expected to be an encrypted content JWE. If the JWE - * creator set the (optional) {@link Header#getContentType() contentType} header value, the application may - * inspect that value to determine how to convert the byte array to the final content type as desired. + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * invokes the specified {@code handler} with the resulting JWT or JWS instance. + *

+ *

If you are confident of the format of the JWT before parsing, you can create an anonymous subclass using the + * {@link io.jsonwebtoken.JwtHandlerAdapter JwtHandlerAdapter} and override only the methods you know are relevant + * for your use case(s), for example:

+ *

+ *

+     * String compactJwt = request.getParameter("jwt"); //we are confident this is a signed JWS
      *
-     * 

This is a convenience method logically equivalent to the following:

+ * String subject = Jwts.parser().setSigningKey(key).parse(compactJwt, new JwtHandlerAdapter<String>() { + * @Override + * public String onClaimsJws(Jws<Claims> jws) { + * return jws.getBody().getSubject(); + * } + * }); + *
+ *

+ *

If you know the JWT string can be only one type of JWT, then it is even easier to invoke one of the + * following convenience methods instead of this one:

+ *

+ *

    + *
  • {@link #parsePlaintextJwt(String)}
  • + *
  • {@link #parseClaimsJwt(String)}
  • + *
  • {@link #parsePlaintextJws(String)}
  • + *
  • {@link #parseClaimsJws(String)}
  • + *
* - *
-     * {@link #parse(CharSequence) parse}(jwe).{@link Jwt#accept(JwtVisitor) accept}({@link
-     * Jwe#CONTENT});
+ * @param jwt the compact serialized JWT to parse + * @return the result returned by the {@code JwtHandler} + * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). + * Invalid JWTs should not be trusted and should be discarded. + * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail + * signature validation should not be trusted and should be discarded. + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace, or if the + * {@code handler} is {@code null}. + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + * @see #parse(String) + * @since 0.2 + */ + T parse(String jwt, JwtHandler handler) + throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * returns + * the resulting unsigned plaintext JWT instance. + *

+ *

This is a convenience method that is usable if you are confident that the compact string argument reflects an + * unsigned plaintext JWT. An unsigned plaintext JWT has a String (non-JSON) body payload and it is not + * cryptographically signed.

+ *

+ *

If the compact string presented does not reflect an unsigned plaintext JWT with non-JSON string body, + * an {@link UnsupportedJwtException} will be thrown.

* - * @param jwe a compact encrypted content JWE. - * @return the parsed decrypted content JWE. - * @throws UnsupportedJwtException if the {@code jwe} argument does not represent an encrypted content JWE - * @throws JwtException if the {@code jwe} string cannot be parsed or validated as required. - * @throws IllegalArgumentException if the {@code jwe} string is {@code null} or empty or only whitespace - * @see #parse(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.12.0 + * @param plaintextJwt a compact serialized unsigned plaintext JWT string. + * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. + * @throws UnsupportedJwtException if the {@code plaintextJwt} argument does not represent an unsigned plaintext + * JWT + * @throws MalformedJwtException if the {@code plaintextJwt} string is not a valid JWT + * @throws SignatureException if the {@code plaintextJwt} string is actually a JWS and signature validation + * fails + * @throws IllegalArgumentException if the {@code plaintextJwt} string is {@code null} or empty or only whitespace + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 */ - Jwe parseEncryptedContent(CharSequence jwe) throws JwtException, IllegalArgumentException; + Jwt parsePlaintextJwt(String plaintextJwt) + throws UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; /** - * Parses the {@code jwe} argument, expected to be an encrypted {@code Claims} JWE. This is a - * convenience method logically equivalent to the following: + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * returns + * the resulting unsigned plaintext JWT instance. + *

+ *

This is a convenience method that is usable if you are confident that the compact string argument reflects an + * unsigned Claims JWT. An unsigned Claims JWT has a {@link Claims} body and it is not cryptographically + * signed.

+ *

+ *

If the compact string presented does not reflect an unsigned Claims JWT, an + * {@link UnsupportedJwtException} will be thrown.

* - *
-     * {@link #parse(CharSequence) parse}(jwe).{@link Jwt#accept(JwtVisitor) accept}({@link
-     * Jwe#CLAIMS});
+ * @param claimsJwt a compact serialized unsigned Claims JWT string. + * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. + * @throws UnsupportedJwtException if the {@code claimsJwt} argument does not represent an unsigned Claims JWT + * @throws MalformedJwtException if the {@code claimsJwt} string is not a valid JWT + * @throws SignatureException if the {@code claimsJwt} string is actually a JWS and signature validation + * fails + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the {@code claimsJwt} string is {@code null} or empty or only whitespace + * @see #parsePlaintextJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 + */ + Jwt parseClaimsJwt(String claimsJwt) + throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWS string based on the builder's current configuration state and + * returns + * the resulting plaintext JWS instance. + *

+ *

This is a convenience method that is usable if you are confident that the compact string argument reflects a + * plaintext JWS. A plaintext JWS is a JWT with a String (non-JSON) body (payload) that has been + * cryptographically signed.

+ *

+ *

If the compact string presented does not reflect a plaintext JWS, an {@link UnsupportedJwtException} + * will be thrown.

* - * @param jwe a compact encrypted Claims JWE. - * @return the parsed decrypted Claims JWE. - * @throws UnsupportedJwtException if the {@code jwe} argument does not represent an encrypted Claims JWE. - * @throws JwtException if the {@code jwe} string cannot be parsed or validated as required. - * @throws IllegalArgumentException if the {@code jwe} string is {@code null} or empty or only whitespace - * @see #parse(CharSequence) - * @see Jwt#accept(JwtVisitor) - * @since 0.12.0 + * @param plaintextJws a compact serialized JWS string. + * @return the {@link Jws Jws} instance that reflects the specified compact JWS string. + * @throws UnsupportedJwtException if the {@code plaintextJws} argument does not represent an plaintext JWS + * @throws MalformedJwtException if the {@code plaintextJws} string is not a valid JWS + * @throws SignatureException if the {@code plaintextJws} JWS signature validation fails + * @throws IllegalArgumentException if the {@code plaintextJws} string is {@code null} or empty or only whitespace + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parseClaimsJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 */ - Jwe parseEncryptedClaims(CharSequence jwe) throws JwtException, IllegalArgumentException; + Jws parsePlaintextJws(String plaintextJws) + throws UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWS string based on the builder's current configuration state and + * returns + * the resulting Claims JWS instance. + *

+ *

This is a convenience method that is usable if you are confident that the compact string argument reflects a + * Claims JWS. A Claims JWS is a JWT with a {@link Claims} body that has been cryptographically signed.

+ *

+ *

If the compact string presented does not reflect a Claims JWS, an {@link UnsupportedJwtException} will be + * thrown.

+ * + * @param claimsJws a compact serialized Claims JWS string. + * @return the {@link Jws Jws} instance that reflects the specified compact Claims JWS string. + * @throws UnsupportedJwtException if the {@code claimsJws} argument does not represent an Claims JWS + * @throws MalformedJwtException if the {@code claimsJws} string is not a valid JWS + * @throws SignatureException if the {@code claimsJws} JWS signature validation fails + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the {@code claimsJws} string is {@code null} or empty or only whitespace + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 + */ + Jws parseClaimsJws(String claimsJws) + throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtParserBuilder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtParserBuilder.java (.../JwtParserBuilder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtParserBuilder.java (.../JwtParserBuilder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,134 +15,32 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.io.CompressionAlgorithm; import io.jsonwebtoken.io.Decoder; import io.jsonwebtoken.io.Deserializer; -import io.jsonwebtoken.lang.Builder; -import io.jsonwebtoken.lang.Conjunctor; -import io.jsonwebtoken.lang.NestedCollection; -import io.jsonwebtoken.security.AeadAlgorithm; -import io.jsonwebtoken.security.KeyAlgorithm; -import io.jsonwebtoken.security.SecureDigestAlgorithm; -import javax.crypto.SecretKey; -import java.io.InputStream; import java.security.Key; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.PublicKey; import java.util.Date; import java.util.Map; /** * A builder to construct a {@link JwtParser}. Example usage: *
{@code
- *     Jwts.parser()
+ *     Jwts.parserBuilder()
+ *         .setSigningKey(...)
  *         .requireIssuer("https://issuer.example.com")
- *         .verifyWith(...)
  *         .build()
  *         .parse(jwtString)
  * }
- * * @since 0.11.0 */ -@SuppressWarnings("JavadocLinkAsPlainText") -public interface JwtParserBuilder extends Builder { +public interface JwtParserBuilder { /** - * Enables parsing of Unsecured JWTs (JWTs with an 'alg' (Algorithm) header value of - * 'none' or missing the 'alg' header entirely). Be careful when calling this method - one should fully understand - * Unsecured JWS Security Considerations - * before enabling this feature. - *

If this method is not called, Unsecured JWTs are disabled by default as mandated by - * RFC 7518, Section - * 3.6.

- * - * @return the builder for method chaining. - * @see Unsecured JWS Security Considerations - * @see Using the Algorithm "none" - * @see Jwts.SIG#NONE - * @see #unsecuredDecompression() - * @since 0.12.0 - */ - JwtParserBuilder unsecured(); - - /** - * If the parser is {@link #unsecured()}, 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 - * In the - * Compression Hornet’s Nest: A Security Study of Data Compression in Network Services. - * - *

Because this behavior is only relevant if the parser is unsecured, - * calling this method without also calling {@link #unsecured()} 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.

- * - * As is the case for {@link #unsecured()}, be careful when calling this method - one should fully - * understand - * Unsecured JWS Security Considerations - * before enabling this feature. - * - * @return the builder for method chaining. - * @see Unsecured JWS Security Considerations - * @see In the - * Compression Hornet’s Nest: A Security Study of Data Compression in Network Services - * @see Jwts.SIG#NONE - * @see #unsecured() - * @since 0.12.0 - */ - JwtParserBuilder unsecuredDecompression(); - - /** - * Configures the {@link ProtectedHeader} parameter names used in JWT extensions supported by the application. If - * the parser encounters a Protected JWT that {@link ProtectedHeader#getCritical() requires} extensions, and - * those extensions' header names are not specified via this method, the parser will reject that JWT. - * - *

The collection's {@link Conjunctor#and() and()} method returns to the builder for continued parser - * configuration, for example:

- *
-     * parserBuilder.critical().add("headerName").{@link Conjunctor#and() and()} // etc...
- * - *

Extension Behavior

- * - *

The {@code critical} collection only identifies header parameter names that are used in extensions supported - * by the application. Application developers, not JJWT, MUST perform the associated extension behavior - * using the parsed JWT.

- * - *

Continued Parser Configuration

- *

When finished, use the collection's - * {@link Conjunctor#and() and()} method to continue parser configuration, for example: - *

-     * Jwts.parser()
-     *     .critical().add("headerName").{@link Conjunctor#and() and()} // return parent
-     * // resume parser configuration...
- * - * @return the {@link NestedCollection} to use for {@code crit} configuration. - * @see ProtectedHeader#getCritical() - * @since 0.12.0 - */ - NestedCollection critical(); - - /** - * Sets the JCA Provider to use during cryptographic signature and key decryption operations, or {@code null} if the - * JCA subsystem preferred provider should be used. - * - * @param provider the JCA Provider to use during cryptographic signature and decryption operations, or {@code null} - * if the JCA subsystem preferred provider should be used. - * @return the builder for method chaining. - * @since 0.12.0 - */ - JwtParserBuilder provider(Provider provider); - - /** * Ensures that the specified {@code jti} exists in the parsed JWT. If missing or if the parsed * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param id the required value of the {@code jti} header parameter. + * @param id * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -154,7 +52,7 @@ * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param subject the required value of the {@code sub} header parameter. + * @param subject * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -163,10 +61,10 @@ /** * Ensures that the specified {@code aud} exists in the parsed JWT. If missing or if the parsed - * value does not contain the specified value, an exception will be thrown indicating that the + * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param audience the required value of the {@code aud} header parameter. + * @param audience * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -178,7 +76,7 @@ * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param issuer the required value of the {@code iss} header parameter. + * @param issuer * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -190,7 +88,7 @@ * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param issuedAt the required value of the {@code iat} header parameter. + * @param issuedAt * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -202,7 +100,7 @@ * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param expiration the required value of the {@code exp} header parameter. + * @param expiration * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -214,7 +112,7 @@ * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param notBefore the required value of the {@code npf} header parameter. + * @param notBefore * @return the parser builder for method chaining * @see MissingClaimException * @see IncorrectClaimException @@ -226,8 +124,8 @@ * value does not equal the specified value, an exception will be thrown indicating that the * JWT is invalid and may not be used. * - * @param claimName the name of a claim that must exist - * @param value the required value of the specified {@code claimName} + * @param claimName + * @param value * @return the parser builder for method chaining. * @see MissingClaimException * @see IncorrectClaimException @@ -240,78 +138,49 @@ * * @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 0.12.0 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 0.12.0 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. + * any such value would cause numeric overflow when multiplying by 1000 to obtain a millisecond value. */ - @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. - * - * @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. - */ - JwtParserBuilder clockSkewSeconds(long seconds) throws IllegalArgumentException; - - /** - *

Deprecation Notice

- * - *

This method has been deprecated since 0.12.0 and will be removed before 1.0. It was not - * readily obvious to many JJWT users that this method was for bytes that pertained only to HMAC - * {@code SecretKey}s, and could be confused with keys of other types. It is better to obtain a type-safe - * {@link SecretKey} instance and call {@link #verifyWith(SecretKey)} instead.

- * - *

Previous Documentation

- * - *

Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not - * a JWS (no signature), this key is not used.

- * + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

*

Note that this key MUST be a valid key for the signature algorithm found in the JWT header * (as the {@code alg} header parameter).

- * + *

*

This method overwrites any previously set key.

* * @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 0.12.0 in favor of {@link #verifyWith(SecretKey)} for type safety and name - * congruence with the {@link #decryptWith(SecretKey)} method. */ - @Deprecated JwtParserBuilder setSigningKey(byte[] key); /** - *

Deprecation Notice: Deprecated as of 0.10.0, will be removed in 1.0.0

+ * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. * + *

Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

+ * + *

This method overwrites any previously set key.

+ * + *

This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting + * byte array is used to invoke {@link #setSigningKey(byte[])}.

+ * + *

Deprecation Notice: Deprecated as of 0.10.0, will be removed in 1.0.0

+ * *

This method has been deprecated because the {@code key} argument for this method can be confusing: keys for * cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were * obtained from the String argument.

@@ -330,429 +199,78 @@ * StackOverflow answer explaining why raw (non-base64-encoded) strings are almost always incorrect for * signature operations.

* - *

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.

+ *

Finally, please use the {@link #setSigningKey(Key) setSigningKey(Key)} instead, as this method and the + * {@code byte[]} variant will be removed before the 1.0.0 release.

* - *

Previous JavaDoc

- * - *

This is a convenience method that equates to the following:

- * - *
-     * 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(SecretKey) verifyWith}(key);
- * - * @param base64EncodedSecretKey BASE64-encoded HMAC-SHA key bytes used to create a Key which will be used to - * verify all encountered JWS digital signatures. + * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signature verification key to use to validate + * any discovered JWS digital signature. * @return the parser builder for method chaining. - * @deprecated in favor of {@link #verifyWith(SecretKey)} as explained in the above Deprecation Notice, - * and will be removed in 1.0.0. */ - @Deprecated JwtParserBuilder setSigningKey(String base64EncodedSecretKey); /** - *

Deprecation Notice

+ * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

+ *

Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

+ *

+ *

This method overwrites any previously set key.

* - *

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 0.12.0 in favor of - * {@link #verifyWith(SecretKey)} for type safety, to reflect accurate naming of the concept, and for name - * congruence with the {@link #decryptWith(SecretKey)} method.

- * - *

This method merely delegates directly to {@link #verifyWith(SecretKey)} or {@link #verifyWith(PublicKey)}}.

- * - * @param key the algorithm-specific signature verification key to use to verify all encountered JWS digital - * signatures. + * @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital + * signature. * @return the parser builder for method chaining. - * @deprecated since 0.12.0 in favor of {@link #verifyWith(SecretKey)} for naming congruence with the - * {@link #decryptWith(SecretKey)} method. */ - @Deprecated JwtParserBuilder setSigningKey(Key key); /** - * 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. - * - *

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 SecretKey. This also implies that this key - * MUST be a valid key for the signature algorithm ({@code alg} header) used for the JWS.

- * - *

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.

- * - *

Calling this method overrides any previously set signature verification key.

- * - * @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 0.12.0 - */ - JwtParserBuilder verifyWith(SecretKey key); - - /** - * 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. - * - *

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 - * MUST be a valid key for the signature algorithm ({@code alg} header) used for the JWS.

- * - *

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.

- * - *

Calling this method overrides any previously set signature verification key.

- * - * @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 0.12.0 - */ - 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. - * - *

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 SecretKey. This also implies that this key MUST 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.

- * - *

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.

- * - *

Calling this method overrides any previously set decryption key.

- * - * @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 0.12.0 - */ - 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. - * - *

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 MUST be a valid - * key for the JWE's key management algorithm ({@code alg} header).

- * - *

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.

- * - *

Calling this method overrides any previously set decryption key.

- * - * @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 0.12.0 - */ - JwtParserBuilder decryptWith(PrivateKey key); - - /** - * Sets the {@link Locator} used to acquire any signature verification or decryption key needed during parsing. - *
    - *
  • If the parsed String is a JWS, the {@code Locator} will be called to find the appropriate key - * necessary to verify the JWS signature.
  • - *
  • If the parsed String is a JWE, it will be called to find the appropriate decryption key.
  • - *
- * - *

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:

- * - *
-     * Jws<Claims> jws = Jwts.parser().keyLocator(new Locator<Key>() {
-     *         @Override
-     *         public Key locate(Header<?> header) {
-     *             if (header instanceof JwsHeader) {
-     *                 return getSignatureVerificationKey((JwsHeader)header); // implement me
-     *             } else {
-     *                 return getDecryptionKey((JweHeader)header); // implement me
-     *             }
-     *         }})
-     *     .build()
-     *     .parseSignedClaims(compact);
-     * 
- * - *

A Key {@code Locator} is invoked once during parsing before performing decryption or signature verification.

- * - *

Provider-constrained Keys

- * - *

If any verification or decryption key returned from a Key {@code Locator} must be used with a specific - * security {@link Provider} (such as for PKCS11 or Hardware Security Module (HSM) keys), you must make that - * Provider available for JWT parsing in one of 3 ways, listed in order of recommendation and simplicity:

- * - *
    - *
  1. - * Configure the Provider in the JVM, either by modifying the {@code java.security} file or by - * registering the Provider dynamically via - * {@link java.security.Security#addProvider(Provider) Security.addProvider(Provider)}. This is the - * recommended approach so you do not need to modify code anywhere that may need to parse JWTs.
  2. - *
  3. Specify the {@code Provider} as the {@code JwtParser} default via {@link #provider(Provider)}. This will - * ensure the provider is used by default with all located keys unless overridden by a - * key-specific Provider. This is only recommended when you are confident that all JWTs encountered by the - * parser instance will use keys attributed to the same {@code Provider}, unless overridden by a specific - * key.
  4. - *
  5. Associate the {@code Provider} with a specific key so it is used for that key only. This option - * is useful if some located keys require a specific provider, while other located keys can assume a - * default provider.
  6. - *
- * - *

If you need to use option #3, you associate a key for the {@code JwtParser}'s needs by using a - * key builder before returning the key as the {@code Locator} return value. For example:

- *
-     *     public Key locate(Header<?> header) {
-     *         PrivateKey key = findKey(header); // or SecretKey
-     *         Provider keySpecificProvider = getKeyProvider(key); // implement me
-     *         // associate the key with its required provider:
-     *         return Keys.builder(key).provider(keySpecificProvider).build();
-     *     }
- * - * @param keyLocator the locator used to retrieve decryption or signature verification keys. - * @return the parser builder for method chaining. - * @since 0.12.0 - */ - JwtParserBuilder keyLocator(Locator keyLocator); - - /** - *

Deprecation Notice

- * - *

This method has been deprecated as of JJWT version 0.12.0 because it only supports key location - * for JWSs (signed JWTs) instead of both signed (JWS) and encrypted (JWE) scenarios. Use the - * {@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.

- * - *

Previous Documentation

- * - *

Sets the {@link SigningKeyResolver} used to acquire the signing key that should be used to verify - * a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used.

- * + * Sets the {@link SigningKeyResolver} used to acquire the signing key that should be used to verify + * a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used. + *

*

Specifying a {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing - * the JWT and the JWT header or payload (content byte array or Claims) must be inspected first to determine how to + * the JWT and the JWT header or payload (plaintext body or Claims) must be inspected first to determine how to * look up the signing key. Once returned by the resolver, the JwtParser will then verify the JWS signature with the * returned key. For example:

- * + *

*

      * Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
      *         @Override
      *         public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
      *             //inspect the header or claims, lookup and return the signing key
      *             return getSigningKey(header, claims); //implement me
      *         }})
-     *     .build().parseSignedClaims(compact);
+     *     .parseClaimsJws(compact);
      * 
- * + *

*

A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.

+ *

+ *

This method should only be used if a signing key is not provided by the other {@code setSigningKey*} builder + * methods.

* * @param signingKeyResolver the signing key resolver used to retrieve the signing key. * @return the parser builder for method chaining. - * @deprecated since 0.12.0 in favor of {@link #keyLocator(Locator)} */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated JwtParserBuilder setSigningKeyResolver(SigningKeyResolver signingKeyResolver); /** - * Configures the parser's supported {@link AeadAlgorithm}s used to decrypt JWE payloads. If the parser - * encounters a JWE {@link JweHeader#getEncryptionAlgorithm() enc} header value that equals an - * AEAD algorithm's {@link Identifiable#getId() id}, that algorithm will be used to decrypt the JWT - * payload. - * - *

The collection's {@link Conjunctor#and() and()} method returns to the builder for continued parser - * configuration, for example:

- *
-     * parserBuilder.enc().add(anAeadAlgorithm).{@link Conjunctor#and() and()} // etc...
- * - *

Standard Algorithms and Overrides

- * - *

All JWA-standard AEAD encryption algorithms in the {@link Jwts.ENC} registry are supported by default and - * do not need to be added. The collection may be useful however for removing some algorithms (for example, - * any algorithms not used by the application, or those not compatible with application security requirements), - * or for adding custom implementations.

- * - *

Custom Implementations

- * - *

There may be only one registered {@code AeadAlgorithm} per algorithm {@code id}, and any algorithm - * instances that are {@link io.jsonwebtoken.lang.CollectionMutator#add(Object) add}ed to this collection with a - * duplicate ID will evict any existing or previously-added algorithm with the same {@code id}. But beware: - * - *

- * Any algorithm instance added to this collection with a JWA-standard {@link Identifiable#getId() id} will - * replace (override) the JJWT standard algorithm implementation.
- * - *

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).

- * - * @return the {@link NestedCollection} to use to configure the AEAD encryption algorithms available when parsing. - * @see JwtBuilder#encryptWith(Key, KeyAlgorithm, AeadAlgorithm) - * @see Jwts.ENC - * @see "enc" (Encryption Algorithm) Header Parameter - * @see Encryption Algorithm Name (id) requirements - * @since 0.12.0 - */ - NestedCollection enc(); - - /** - * Configures the parser's supported {@link KeyAlgorithm}s used to obtain a JWE's decryption key. If the - * parser encounters a JWE {@link JweHeader#getAlgorithm()} alg} header value that equals a {@code KeyAlgorithm}'s - * {@link Identifiable#getId() id}, that key algorithm will be used to obtain the JWE's decryption key. - * - *

The collection's {@link Conjunctor#and() and()} method returns to the builder for continued parser - * configuration, for example:

- *
-     * parserBuilder.key().add(aKeyAlgorithm).{@link Conjunctor#and() and()} // etc...
- * - *

Standard Algorithms and Overrides

- * - *

All JWA-standard key encryption algorithms in the {@link Jwts.KEY} registry are supported by default and - * do not need to be added. The collection may be useful however for removing some algorithms (for example, - * any algorithms not used by the application, or those not compatible with application security requirements), - * or for adding custom implementations.

- * - *

Custom Implementations

- * - *

There may be only one registered {@code KeyAlgorithm} per algorithm {@code id}, and any algorithm - * instances that are {@link io.jsonwebtoken.lang.CollectionMutator#add(Object) add}ed to this collection with a - * duplicate ID will evict any existing or previously-added algorithm with the same {@code id}. But beware: - * - *

- * Any algorithm instance added to this collection with a JWA-standard {@link Identifiable#getId() id} will - * replace (override) the JJWT standard algorithm implementation.
- * - *

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).

- * - * @return the {@link NestedCollection} to use to configure the key algorithms available when parsing. - * @see JwtBuilder#encryptWith(Key, KeyAlgorithm, AeadAlgorithm) - * @see Jwts.KEY - * @see JWE "alg" (Algorithm) Header Parameter - * @see Key Algorithm Name (id) requirements - * @since 0.12.0 - */ - NestedCollection, JwtParserBuilder> key(); - - /** - * Configures the parser's supported - * {@link io.jsonwebtoken.security.SignatureAlgorithm SignatureAlgorithm} and - * {@link io.jsonwebtoken.security.MacAlgorithm MacAlgorithm}s used to verify JWS signatures. If the parser - * encounters a JWS {@link ProtectedHeader#getAlgorithm() alg} header value that equals a signature or MAC - * algorithm's {@link Identifiable#getId() id}, that algorithm will be used to verify the JWS signature. - * - *

The collection's {@link Conjunctor#and() and()} method returns to the builder for continued parser - * configuration, for example:

- *
-     * parserBuilder.sig().add(aSignatureAlgorithm).{@link Conjunctor#and() and()} // etc...
- * - *

Standard Algorithms and Overrides

- * - *

All JWA-standard signature and MAC algorithms in the {@link Jwts.SIG} registry are supported by default and - * do not need to be added. The collection may be useful however for removing some algorithms (for example, - * any algorithms not used by the application, or those not compatible with application security requirements), or - * for adding custom implementations.

- * - *

Custom Implementations

- * - *

There may be only one registered {@code SecureDigestAlgorithm} per algorithm {@code id}, and any algorithm - * instances that are {@link io.jsonwebtoken.lang.CollectionMutator#add(Object) add}ed to this collection with a - * duplicate ID will evict any existing or previously-added algorithm with the same {@code id}. But beware: - * - *

- * Any algorithm instance added to this collection with a JWA-standard {@link Identifiable#getId() id} will - * replace (override) the JJWT standard algorithm implementation.
- * - *

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).

- * - * @return the {@link NestedCollection} to use to configure the signature and MAC algorithms available when parsing. - * @see JwtBuilder#signWith(Key, SecureDigestAlgorithm) - * @see Jwts.SIG - * @see JWS "alg" (Algorithm) Header Parameter - * @see Algorithm Name (id) requirements - * @since 0.12.0 - */ - NestedCollection, JwtParserBuilder> sig(); - - /** - * Configures the parser's supported {@link CompressionAlgorithm}s used to decompress JWT payloads. If the parser - * encounters a JWT {@link ProtectedHeader#getCompressionAlgorithm() zip} header value that equals a - * compression algorithm's {@link Identifiable#getId() id}, that algorithm will be used to decompress the JWT - * payload. - * - *

The collection's {@link Conjunctor#and() and()} method returns to the builder for continued parser - * configuration, for example:

- *
-     * parserBuilder.zip().add(aCompressionAlgorithm).{@link Conjunctor#and() and()} // etc...
- * - *

Standard Algorithms and Overrides

- * - *

All JWA-standard compression algorithms in the {@link Jwts.ZIP} registry are supported by default and - * do not need to be added. The collection may be useful however for removing some algorithms (for example, - * any algorithms not used by the application), or for adding custom implementations.

- * - *

Custom Implementations

- * - *

There may be only one registered {@code CompressionAlgorithm} per algorithm {@code id}, and any algorithm - * instances that are {@link io.jsonwebtoken.lang.CollectionMutator#add(Object) add}ed to this collection with a - * duplicate ID will evict any existing or previously-added algorithm with the same {@code id}. But beware: - * - *

- * Any algorithm instance added to this collection with a JWA-standard {@link Identifiable#getId() id} will - * replace (override) the JJWT standard algorithm implementation.
- * - *

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).

- * - * @return the {@link NestedCollection} to use to configure the compression algorithms available when parsing. - * @see JwtBuilder#compressWith(CompressionAlgorithm) - * @see Jwts.ZIP - * @see "zip" (Compression Algorithm) Header Parameter - * @see Compression Algorithm Name (id) requirements - * @since 0.12.0 - */ - NestedCollection zip(); - - /** - *

Deprecated as of JJWT 0.12.0. This method will be removed before the 1.0 release.

- * - *

This method has been deprecated as of JJWT version 0.12.0 because it imposed unnecessary - * implementation requirements on application developers when simply adding to a compression algorithm collection - * would suffice. Use the {@link #zip()} method instead to add - * any custom algorithm implementations without needing to also implement a Locator implementation.

- * - *

Previous Documentation

- *

* Sets the {@link CompressionCodecResolver} used to acquire the {@link CompressionCodec} that should be used to * decompress the JWT body. If the parsed JWT is not compressed, this resolver is not used. - * - *

WARNING: Compression is not defined by the JWS Specification - only the JWE Specification - and it is - * not expected that other libraries (including JJWT versions < 0.6.0) are able to consume a compressed JWS - * body correctly.

- * - *

Default Support

- * - *

JJWT's default {@link JwtParser} implementation supports both the {@link Jwts.ZIP#DEF DEF} - * and {@link Jwts.ZIP#GZIP GZIP} algorithms by default - you do not need to + *

NOTE: Compression is not defined by the JWT Specification, and it is not expected that other libraries + * (including JJWT versions < 0.6.0) are able to consume a compressed JWT body correctly. This method is only + * useful if the compact JWT was compressed with JJWT >= 0.6.0 or another library that you know implements + * the same behavior.

+ *

Default Support

+ *

JJWT's default {@link JwtParser} implementation supports both the + * {@link CompressionCodecs#DEFLATE DEFLATE} + * and {@link CompressionCodecs#GZIP GZIP} algorithms by default - you do not need to * specify a {@code CompressionCodecResolver} in these cases.

+ *

However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you must implement + * your own {@link CompressionCodecResolver} and specify that via this method and also when + * {@link io.jsonwebtoken.JwtBuilder#compressWith(CompressionCodec) building} JWTs.

* * @param compressionCodecResolver the compression codec resolver used to decompress the JWT body. * @return the parser builder for method chaining. - * @deprecated since 0.12.0 in favor of {@link #zip()}. This method will be removed before the - * 1.0 release. */ - @Deprecated JwtParserBuilder setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver); /** @@ -763,27 +281,10 @@ * * @param base64UrlDecoder the decoder to use when Base64Url-decoding * @return the parser builder for method chaining. - * @deprecated since 0.12.0 in favor of {@link #b64Url(Decoder)}. This method will be removed - * before the JJWT 1.0 release. */ - @Deprecated - JwtParserBuilder base64UrlDecodeWith(Decoder base64UrlDecoder); + JwtParserBuilder base64UrlDecodeWith(Decoder base64UrlDecoder); /** - * Perform Base64Url decoding during parsing with the specified {@code InputStream} Decoder. - * The Decoder's {@link Decoder#decode(Object) decode} method will be given a source {@code InputStream} to - * wrap, and the resulting (wrapping) {@code InputStream} will be used for reading , ensuring automatic - * Base64URL-decoding during read operations. - * - *

JJWT uses a spec-compliant decoder that works on all supported JDK versions, but you may call this method - * to specify a different stream decoder if desired.

- * - * @param base64UrlDecoder the stream decoder to use when Base64Url-decoding - * @return the parser builder for method chaining. - */ - JwtParserBuilder b64Url(Decoder 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. @@ -795,31 +296,11 @@ * * @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 0.12.0 in favor of {@link #json(Deserializer)}. - * This method will be removed before the JJWT 1.0 release. */ - @Deprecated - JwtParserBuilder deserializeJsonWith(Deserializer> deserializer); + JwtParserBuilder deserializeJsonWith(Deserializer> deserializer); /** - * Uses the specified JSON {@link Deserializer} to deserialize JSON (UTF-8 byte streams) into Java Map objects. - * This is used by the parser after Base64Url-decoding to convert JWT/JWS/JWT headers and Claims into Java Map - * instances. - * - *

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.

- * - * @param deserializer the deserializer to use to deserialize JSON (UTF-8 byte streams) into Map instances. - * @return the builder for method chaining. - * @since 0.12.0 - */ - JwtParserBuilder json(Deserializer> deserializer); - - /** * Returns an immutable/thread-safe {@link JwtParser} created from the configuration from this JwtParserBuilder. - * * @return an immutable/thread-safe JwtParser created from the configuration from this JwtParserBuilder. */ JwtParser build(); Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/JwtVisitor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwts.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwts.java (.../Jwts.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Jwts.java (.../Jwts.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,1038 +15,119 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.io.CompressionAlgorithm; -import io.jsonwebtoken.lang.Builder; import io.jsonwebtoken.lang.Classes; -import io.jsonwebtoken.lang.Registry; -import io.jsonwebtoken.security.AeadAlgorithm; -import io.jsonwebtoken.security.KeyAlgorithm; -import io.jsonwebtoken.security.KeyPairBuilderSupplier; -import io.jsonwebtoken.security.MacAlgorithm; -import io.jsonwebtoken.security.Password; -import io.jsonwebtoken.security.SecretKeyAlgorithm; -import io.jsonwebtoken.security.SecureDigestAlgorithm; -import io.jsonwebtoken.security.SignatureAlgorithm; -import io.jsonwebtoken.security.X509Builder; -import javax.crypto.SecretKey; -import java.security.Key; -import java.security.PrivateKey; -import java.security.PublicKey; import java.util.Map; /** * Factory class useful for creating instances of JWT interfaces. Using this factory class can be a good * alternative to tightly coupling your code to implementation classes. * - *

Standard Algorithm References

- *

Standard JSON Web Token algorithms used during JWS or JWE building or parsing are available organized by - * algorithm type. Each organized collection of algorithms is available via a constant to allow - * for easy code-completion in IDEs, showing available algorithm instances. For example, when typing:

- *
- * Jwts.// press code-completion hotkeys to suggest available algorithm registry fields
- * Jwts.{@link SIG SIG}.// press hotkeys to suggest individual Digital Signature or MAC algorithms or utility methods
- * Jwts.{@link ENC ENC}.// press hotkeys to suggest individual encryption algorithms or utility methods
- * Jwts.{@link KEY KEY}.// press hotkeys to suggest individual key algorithms or utility methods
- * * @since 0.1 */ public final class Jwts { + private static final Class[] MAP_ARG = new Class[]{Map.class}; - // do not change this visibility. Raw type method signature not be publicly exposed: - @SuppressWarnings("unchecked") - private static T get(Registry registry, String id) { - return (T) registry.forKey(id); + private Jwts() { } /** - * Constants for all standard JWA - * Cryptographic Algorithms for Content - * Encryption defined in the JSON - * Web Signature and Encryption Algorithms Registry. Each standard algorithm is available as a - * ({@code public static final}) constant for direct type-safe reference in application code. For example: - *
-     * Jwts.builder()
-     *    // ... etc ...
-     *    .encryptWith(aKey, Jwts.ENC.A256GCM) // or A128GCM, A192GCM, etc...
-     *    .build();
- *

They are also available together as a {@link Registry} instance via the {@link #get()} method.

+ * Creates a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs. As this + * is a less common use of JWTs, consider using the {@link #jwsHeader()} factory method instead if you will later + * digitally sign the JWT. * - * @see #get() - * @since 0.12.0 + * @return a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs. */ - public static final class ENC { - - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardEncryptionAlgorithms"; - private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - - /** - * Returns all standard JWA Cryptographic - * Algorithms for Content Encryption defined in the - * JSON Web Signature and Encryption - * Algorithms Registry. - * - * @return all standard JWA content encryption algorithms. - */ - public static Registry get() { - return REGISTRY; - } - - // prevent instantiation - private ENC() { - } - - /** - * {@code AES_128_CBC_HMAC_SHA_256} authenticated encryption algorithm as defined by - * RFC 7518, Section 5.2.3. This algorithm - * requires a 256-bit (32 byte) key. - */ - public static final AeadAlgorithm A128CBC_HS256 = get().forKey("A128CBC-HS256"); - - /** - * {@code AES_192_CBC_HMAC_SHA_384} authenticated encryption algorithm, as defined by - * RFC 7518, Section 5.2.4. This algorithm - * requires a 384-bit (48 byte) key. - */ - public static final AeadAlgorithm A192CBC_HS384 = get().forKey("A192CBC-HS384"); - - /** - * {@code AES_256_CBC_HMAC_SHA_512} authenticated encryption algorithm, as defined by - * RFC 7518, Section 5.2.5. This algorithm - * requires a 512-bit (64 byte) key. - */ - public static final AeadAlgorithm A256CBC_HS512 = get().forKey("A256CBC-HS512"); - - /** - * "AES GCM using 128-bit key" as defined by - * RFC 7518, Section 5.31. This - * algorithm requires a 128-bit (16 byte) key. - * - *

1 Requires Java 8 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath. If on Java 7 or earlier, BouncyCastle will be used automatically if found in the runtime - * classpath.

- */ - public static final AeadAlgorithm A128GCM = get().forKey("A128GCM"); - - /** - * "AES GCM using 192-bit key" as defined by - * RFC 7518, Section 5.31. This - * algorithm requires a 192-bit (24 byte) key. - * - *

1 Requires Java 8 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath. If on Java 7 or earlier, BouncyCastle will be used automatically if found in the runtime - * classpath.

- */ - public static final AeadAlgorithm A192GCM = get().forKey("A192GCM"); - - /** - * "AES GCM using 256-bit key" as defined by - * RFC 7518, Section 5.31. This - * algorithm requires a 256-bit (32 byte) key. - * - *

1 Requires Java 8 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath. If on Java 7 or earlier, BouncyCastle will be used automatically if found in the runtime - * classpath.

- */ - public static final AeadAlgorithm A256GCM = get().forKey("A256GCM"); + public static Header header() { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultHeader"); } /** - * Constants for all JWA (RFC 7518) standard - * Cryptographic Algorithms for Digital Signatures and MACs defined in the - * JSON Web Signature and Encryption Algorithms - * Registry. Each standard algorithm is available as a ({@code public static final}) constant for - * direct type-safe reference in application code. For example: - *
-     * Jwts.builder()
-     *    // ... etc ...
-     *    .signWith(aKey, Jwts.SIG.HS512) // or RS512, PS256, EdDSA, etc...
-     *    .build();
- *

They are also available together as a {@link Registry} instance via the {@link #get()} method.

+ * Creates a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs, populated + * with the specified name/value pairs. As this is a less common use of JWTs, consider using the + * {@link #jwsHeader(java.util.Map)} factory method instead if you will later digitally sign the JWT. * - * @see #get() - * @since 0.12.0 + * @return a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs. */ - public static final class SIG { - - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardSecureDigestAlgorithms"; - private static final Registry> REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - - //prevent instantiation - private SIG() { - } - - /** - * Returns all standard JWA Cryptographic - * Algorithms for Digital Signatures and MACs defined in the - * JSON Web Signature and Encryption - * Algorithms Registry. - * - * @return all standard JWA digital signature and MAC algorithms. - */ - public static Registry> get() { - return REGISTRY; - } - - /** - * The "none" signature algorithm as defined by - * RFC 7518, Section 3.6. This algorithm - * is used only when creating unsecured (not integrity protected) JWSs and is not usable in any other scenario. - * Any attempt to call its methods will result in an exception being thrown. - */ - public static final SecureDigestAlgorithm NONE = Jwts.get(REGISTRY, "none"); - - /** - * {@code HMAC using SHA-256} message authentication algorithm as defined by - * RFC 7518, Section 3.2. This algorithm - * requires a 256-bit (32 byte) key. - */ - public static final MacAlgorithm HS256 = Jwts.get(REGISTRY, "HS256"); - - /** - * {@code HMAC using SHA-384} message authentication algorithm as defined by - * RFC 7518, Section 3.2. This algorithm - * requires a 384-bit (48 byte) key. - */ - public static final MacAlgorithm HS384 = Jwts.get(REGISTRY, "HS384"); - - /** - * {@code HMAC using SHA-512} message authentication algorithm as defined by - * RFC 7518, Section 3.2. This algorithm - * requires a 512-bit (64 byte) key. - */ - public static final MacAlgorithm HS512 = Jwts.get(REGISTRY, "HS512"); - - /** - * {@code RSASSA-PKCS1-v1_5 using SHA-256} signature algorithm as defined by - * RFC 7518, Section 3.3. This algorithm - * requires a 2048-bit key. - */ - public static final SignatureAlgorithm RS256 = Jwts.get(REGISTRY, "RS256"); - - /** - * {@code RSASSA-PKCS1-v1_5 using SHA-384} signature algorithm as defined by - * RFC 7518, Section 3.3. This algorithm - * requires a 2048-bit key, but the JJWT team recommends a 3072-bit key. - */ - public static final SignatureAlgorithm RS384 = Jwts.get(REGISTRY, "RS384"); - - /** - * {@code RSASSA-PKCS1-v1_5 using SHA-512} signature algorithm as defined by - * RFC 7518, Section 3.3. This algorithm - * requires a 2048-bit key, but the JJWT team recommends a 4096-bit key. - */ - public static final SignatureAlgorithm RS512 = Jwts.get(REGISTRY, "RS512"); - - /** - * {@code RSASSA-PSS using SHA-256 and MGF1 with SHA-256} signature algorithm as defined by - * RFC 7518, Section 3.51. - * This algorithm requires a 2048-bit key. - * - *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime - * classpath.

- */ - public static final SignatureAlgorithm PS256 = Jwts.get(REGISTRY, "PS256"); - - /** - * {@code RSASSA-PSS using SHA-384 and MGF1 with SHA-384} signature algorithm as defined by - * RFC 7518, Section 3.51. - * This algorithm requires a 2048-bit key, but the JJWT team recommends a 3072-bit key. - * - *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime - * classpath.

- */ - public static final SignatureAlgorithm PS384 = Jwts.get(REGISTRY, "PS384"); - - /** - * {@code RSASSA-PSS using SHA-512 and MGF1 with SHA-512} signature algorithm as defined by - * RFC 7518, Section 3.51. - * This algorithm requires a 2048-bit key, but the JJWT team recommends a 4096-bit key. - * - *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime - * classpath.

- */ - public static final SignatureAlgorithm PS512 = Jwts.get(REGISTRY, "PS512"); - - /** - * {@code ECDSA using P-256 and SHA-256} signature algorithm as defined by - * RFC 7518, Section 3.4. This algorithm - * requires a 256-bit key. - */ - public static final SignatureAlgorithm ES256 = Jwts.get(REGISTRY, "ES256"); - - /** - * {@code ECDSA using P-384 and SHA-384} signature algorithm as defined by - * RFC 7518, Section 3.4. This algorithm - * requires a 384-bit key. - */ - public static final SignatureAlgorithm ES384 = Jwts.get(REGISTRY, "ES384"); - - /** - * {@code ECDSA using P-521 and SHA-512} signature algorithm as defined by - * RFC 7518, Section 3.4. This algorithm - * requires a 521-bit key. - */ - public static final SignatureAlgorithm ES512 = Jwts.get(REGISTRY, "ES512"); - - /** - * {@code EdDSA} signature algorithm defined by - * RFC 8037, Section 3.1 that requires - * either {@code Ed25519} or {@code Ed448} Edwards Elliptic Curve1 keys. - * - *

KeyPair Generation

- * - *

This instance's {@link KeyPairBuilderSupplier#keyPair() keyPair()} builder creates {@code Ed448} keys, - * and is essentially an alias for - * {@link io.jsonwebtoken.security.Jwks.CRV Jwks.CRV}.{@link io.jsonwebtoken.security.Jwks.CRV#Ed448 Ed448}.{@link KeyPairBuilderSupplier#keyPair() keyPair()}.

- * - *

If you would like to generate an {@code Ed25519} {@code KeyPair} for use with the {@code EdDSA} algorithm, - * you may use the - * {@link io.jsonwebtoken.security.Jwks.CRV Jwks.CRV}.{@link io.jsonwebtoken.security.Jwks.CRV#Ed25519 Ed25519}.{@link KeyPairBuilderSupplier#keyPair() keyPair()} - * builder instead.

- * - *

1This algorithm requires at least JDK 15 or a compatible JCA Provider (like BouncyCastle) in the runtime - * classpath.

- */ - public static final SignatureAlgorithm EdDSA = Jwts.get(REGISTRY, "EdDSA"); + public static Header header(Map header) { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultHeader", MAP_ARG, header); } /** - * Constants for all standard JWA (RFC 7518) - * Cryptographic Algorithms for Key Management. Each standard algorithm is available as a - * ({@code public static final}) constant for direct type-safe reference in application code. For example: - *
-     * Jwts.builder()
-     *    // ... etc ...
-     *    .encryptWith(aKey, Jwts.KEY.ECDH_ES_A256KW, Jwts.ENC.A256GCM)
-     *    .build();
- *

They are also available together as a {@link Registry} instance via the {@link #get()} method.

+ * Returns a new {@link JwsHeader} instance suitable for digitally signed JWTs (aka 'JWS's). * - * @see #get() - * @since 0.12.0 + * @return a new {@link JwsHeader} instance suitable for digitally signed JWTs (aka 'JWS's). + * @see JwtBuilder#setHeader(Header) */ - public static final class KEY { - - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardKeyAlgorithms"; - private static final Registry> REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - - /** - * Returns all standard JWA standard Cryptographic - * Algorithms for Key Management.. - * - * @return all standard JWA Key Management algorithms. - */ - public static Registry> get() { - return REGISTRY; - } - - /** - * Key algorithm reflecting direct use of a shared symmetric key as the JWE AEAD encryption key, as defined - * by RFC 7518 (JWA), Section 4.5. This - * algorithm does not produce encrypted key ciphertext. - */ - public static final KeyAlgorithm DIRECT = Jwts.get(REGISTRY, "dir"); - - /** - * AES Key Wrap algorithm with default initial value using a 128-bit key, as defined by - * RFC 7518 (JWA), Section 4.4. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Encrypts this newly-generated {@code SecretKey} with a 128-bit shared symmetric key using the - * AES Key Wrap algorithm, producing encrypted key ciphertext.
  4. - *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Decrypts the encrypted key ciphertext with the 128-bit shared symmetric key, - * using the AES Key Unwrap algorithm, producing the decryption key plaintext.
  4. - *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. - *
- */ - public static final SecretKeyAlgorithm A128KW = Jwts.get(REGISTRY, "A128KW"); - - /** - * AES Key Wrap algorithm with default initial value using a 192-bit key, as defined by - * RFC 7518 (JWA), Section 4.4. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Encrypts this newly-generated {@code SecretKey} with a 192-bit shared symmetric key using the - * AES Key Wrap algorithm, producing encrypted key ciphertext.
  4. - *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Decrypts the encrypted key ciphertext with the 192-bit shared symmetric key, - * using the AES Key Unwrap algorithm, producing the decryption key plaintext.
  4. - *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. - *
- */ - public static final SecretKeyAlgorithm A192KW = Jwts.get(REGISTRY, "A192KW"); - - /** - * AES Key Wrap algorithm with default initial value using a 256-bit key, as defined by - * RFC 7518 (JWA), Section 4.4. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Encrypts this newly-generated {@code SecretKey} with a 256-bit shared symmetric key using the - * AES Key Wrap algorithm, producing encrypted key ciphertext.
  4. - *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Decrypts the encrypted key ciphertext with the 256-bit shared symmetric key, - * using the AES Key Unwrap algorithm, producing the decryption key plaintext.
  4. - *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. - *
- */ - public static final SecretKeyAlgorithm A256KW = Jwts.get(REGISTRY, "A256KW"); - - /** - * Key wrap algorithm with AES GCM using a 128-bit key, as defined by - * RFC 7518 (JWA), Section 4.7. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.
  4. - *
  5. 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 - * and GCM authentication tag.
  6. - *
  7. Sets the generated initialization vector as the required - * "iv" - * (Initialization Vector) Header Parameter
  8. - *
  9. Sets the resulting GCM authentication tag as the required - * "tag" - * (Authentication Tag) Header Parameter
  10. - *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  12. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Obtains the required initialization vector from the - * "iv" - * (Initialization Vector) Header Parameter
  4. - *
  5. Obtains the required GCM authentication tag from the - * "tag" - * (Authentication Tag) Header Parameter
  6. - *
  7. Decrypts the encrypted key ciphertext with the 128-bit shared symmetric key, the initialization vector - * and GCM authentication tag using the AES GCM Key Unwrap algorithm, producing the decryption key - * plaintext.
  8. - *
  9. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. - *
- */ - public static final SecretKeyAlgorithm A128GCMKW = Jwts.get(REGISTRY, "A128GCMKW"); - - /** - * Key wrap algorithm with AES GCM using a 192-bit key, as defined by - * RFC 7518 (JWA), Section 4.7. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.
  4. - *
  5. 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 - * and GCM authentication tag.
  6. - *
  7. Sets the generated initialization vector as the required - * "iv" - * (Initialization Vector) Header Parameter
  8. - *
  9. Sets the resulting GCM authentication tag as the required - * "tag" - * (Authentication Tag) Header Parameter
  10. - *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  12. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Obtains the required initialization vector from the - * "iv" - * (Initialization Vector) Header Parameter
  4. - *
  5. Obtains the required GCM authentication tag from the - * "tag" - * (Authentication Tag) Header Parameter
  6. - *
  7. Decrypts the encrypted key ciphertext with the 192-bit shared symmetric key, the initialization vector - * and GCM authentication tag using the AES GCM Key Unwrap algorithm, producing the decryption key \ - * plaintext.
  8. - *
  9. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. - *
- */ - public static final SecretKeyAlgorithm A192GCMKW = Jwts.get(REGISTRY, "A192GCMKW"); - - /** - * Key wrap algorithm with AES GCM using a 256-bit key, as defined by - * RFC 7518 (JWA), Section 4.7. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.
  4. - *
  5. 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 - * and GCM authentication tag.
  6. - *
  7. Sets the generated initialization vector as the required - * "iv" - * (Initialization Vector) Header Parameter
  8. - *
  9. Sets the resulting GCM authentication tag as the required - * "tag" - * (Authentication Tag) Header Parameter
  10. - *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  12. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Obtains the required initialization vector from the - * "iv" - * (Initialization Vector) Header Parameter
  4. - *
  5. Obtains the required GCM authentication tag from the - * "tag" - * (Authentication Tag) Header Parameter
  6. - *
  7. Decrypts the encrypted key ciphertext with the 256-bit shared symmetric key, the initialization vector - * and GCM authentication tag using the AES GCM Key Unwrap algorithm, producing the decryption key \ - * plaintext.
  8. - *
  9. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. - *
- */ - public static final SecretKeyAlgorithm A256GCMKW = Jwts.get(REGISTRY, "A256GCMKW"); - - /** - * Key encryption algorithm using PBES2 with HMAC SHA-256 and "A128KW" wrapping - * as defined by - * RFC 7518 (JWA), Section 4.8. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Determines the number of PBDKF2 iterations via the JWE header's - * {@link JweHeader#getPbes2Count() pbes2Count} value. If that value is not set, a suitable number of - * iterations will be chosen based on - * OWASP - * PBKDF2 recommendations and then that value is set as the JWE header {@code pbes2Count} value.
  2. - *
  3. Generates a new secure-random salt input and sets it as the JWE header - * {@link JweHeader#getPbes2Salt() pbes2Salt} value.
  4. - *
  5. 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.
  6. - *
  7. Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  8. - *
  9. 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.
  10. - *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * Content Encryption {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated - * {@link AeadAlgorithm}.
  12. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required PBKDF2 input salt from the - * "p2s" - * (PBES2 Salt Input) Header Parameter
  2. - *
  3. Obtains the required PBKDF2 iteration count from the - * "p2c" - * (PBES2 Count) Header Parameter
  4. - *
  5. Derives the 128-bit Key Encryption Key with the PBES2-HS256 password-based key derivation algorithm, - * using the provided password, obtained salt input, and obtained iteration count as arguments.
  6. - *
  7. Obtains the encrypted key ciphertext embedded in the received JWE.
  8. - *
  9. Decrypts the encrypted key ciphertext with with the {@code A128KW} key unwrap - * algorithm using the 128-bit derived password-based Key Encryption Key from step {@code #3}, - * producing the decryption key plaintext.
  10. - *
  11. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  12. - *
- */ - public static final KeyAlgorithm PBES2_HS256_A128KW = Jwts.get(REGISTRY, "PBES2-HS256+A128KW"); - - /** - * Key encryption algorithm using PBES2 with HMAC SHA-384 and "A192KW" wrapping - * as defined by - * RFC 7518 (JWA), Section 4.8. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Determines the number of PBDKF2 iterations via the JWE header's - * {@link JweHeader#getPbes2Count() pbes2Count} value. If that value is not set, a suitable number of - * iterations will be chosen based on - * OWASP - * PBKDF2 recommendations and then that value is set as the JWE header {@code pbes2Count} value.
  2. - *
  3. Generates a new secure-random salt input and sets it as the JWE header - * {@link JweHeader#getPbes2Salt() pbes2Salt} value.
  4. - *
  5. 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.
  6. - *
  7. Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  8. - *
  9. 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.
  10. - *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * Content Encryption {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated - * {@link AeadAlgorithm}.
  12. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required PBKDF2 input salt from the - * "p2s" - * (PBES2 Salt Input) Header Parameter
  2. - *
  3. Obtains the required PBKDF2 iteration count from the - * "p2c" - * (PBES2 Count) Header Parameter
  4. - *
  5. Derives the 192-bit Key Encryption Key with the PBES2-HS384 password-based key derivation algorithm, - * using the provided password, obtained salt input, and obtained iteration count as arguments.
  6. - *
  7. Obtains the encrypted key ciphertext embedded in the received JWE.
  8. - *
  9. Decrypts the encrypted key ciphertext with with the {@code A192KW} key unwrap - * algorithm using the 192-bit derived password-based Key Encryption Key from step {@code #3}, - * producing the decryption key plaintext.
  10. - *
  11. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  12. - *
- */ - public static final KeyAlgorithm PBES2_HS384_A192KW = Jwts.get(REGISTRY, "PBES2-HS384+A192KW"); - - /** - * Key encryption algorithm using PBES2 with HMAC SHA-512 and "A256KW" wrapping - * as defined by - * RFC 7518 (JWA), Section 4.8. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Determines the number of PBDKF2 iterations via the JWE header's - * {@link JweHeader#getPbes2Count() pbes2Count} value. If that value is not set, a suitable number of - * iterations will be chosen based on - * OWASP - * PBKDF2 recommendations and then that value is set as the JWE header {@code pbes2Count} value.
  2. - *
  3. Generates a new secure-random salt input and sets it as the JWE header - * {@link JweHeader#getPbes2Salt() pbes2Salt} value.
  4. - *
  5. 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.
  6. - *
  7. Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  8. - *
  9. 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.
  10. - *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * Content Encryption {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated - * {@link AeadAlgorithm}.
  12. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required PBKDF2 input salt from the - * "p2s" - * (PBES2 Salt Input) Header Parameter
  2. - *
  3. Obtains the required PBKDF2 iteration count from the - * "p2c" - * (PBES2 Count) Header Parameter
  4. - *
  5. Derives the 256-bit Key Encryption Key with the PBES2-HS512 password-based key derivation algorithm, - * using the provided password, obtained salt input, and obtained iteration count as arguments.
  6. - *
  7. Obtains the encrypted key ciphertext embedded in the received JWE.
  8. - *
  9. Decrypts the encrypted key ciphertext with with the {@code A256KW} key unwrap - * algorithm using the 256-bit derived password-based Key Encryption Key from step {@code #3}, - * producing the decryption key plaintext.
  10. - *
  11. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  12. - *
- */ - public static final KeyAlgorithm PBES2_HS512_A256KW = Jwts.get(REGISTRY, "PBES2-HS512+A256KW"); - - /** - * Key Encryption with {@code RSAES-PKCS1-v1_5}, as defined by - * RFC 7518 (JWA), Section 4.2. - * This algorithm requires a key size of 2048 bits or larger. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. Encrypts this newly-generated {@code SecretKey} with the RSA key wrap algorithm, using the JWE - * recipient's RSA Public Key, producing encrypted key ciphertext.
  4. - *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Receives the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Decrypts the encrypted key ciphertext with the RSA key unwrap algorithm, using the JWE recipient's - * RSA Private Key, producing the decryption key plaintext.
  4. - *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. - *
- */ - public static final KeyAlgorithm RSA1_5 = Jwts.get(REGISTRY, "RSA1_5"); - - /** - * Key Encryption with {@code RSAES OAEP using default parameters}, as defined by - * RFC 7518 (JWA), Section 4.3. - * This algorithm requires a key size of 2048 bits or larger. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. 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.
  4. - *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Receives the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Decrypts the encrypted key ciphertext with the RSA OAEP with SHA-1 and MGF1 key unwrap algorithm, - * using the JWE recipient's RSA Private Key, producing the decryption key plaintext.
  4. - *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. - *
- */ - public static final KeyAlgorithm RSA_OAEP = Jwts.get(REGISTRY, "RSA-OAEP"); - - /** - * Key Encryption with {@code RSAES OAEP using SHA-256 and MGF1 with SHA-256}, as defined by - * RFC 7518 (JWA), Section 4.3. - * This algorithm requires a key size of 2048 bits or larger. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. - *
  3. 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.
  4. - *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Receives the encrypted key ciphertext embedded in the received JWE.
  2. - *
  3. Decrypts the encrypted key ciphertext with the RSA OAEP with SHA-256 and MGF1 key unwrap algorithm, - * using the JWE recipient's RSA Private Key, producing the decryption key plaintext.
  4. - *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. - *
- */ - public static final KeyAlgorithm RSA_OAEP_256 = Jwts.get(REGISTRY, "RSA-OAEP-256"); - - /** - * Key Agreement with {@code ECDH-ES using Concat KDF} as defined by - * RFC 7518 (JWA), Section 4.6. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the - * JWE recipient's EC Public Key.
  2. - *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key - * and the JWE recipient's EC Public Key.
  4. - *
  5. Derives a symmetric Content - * Encryption {@code SecretKey} with the Concat KDF algorithm using the - * generated shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. - *
  7. Sets the generated EC key pair's Public Key as the required - * "epk" - * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. - *
  9. Returns the derived symmetric {@code SecretKey} for JJWT to use to encrypt the entire JWE with the - * associated {@link AeadAlgorithm}. Encrypted key ciphertext is not produced with this algorithm, so - * the resulting JWE will not contain any embedded key ciphertext.
  10. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the - * "epk" - * (Ephemeral Public Key) Header Parameter.
  2. - *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. - *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key - * and the JWE recipient's EC Private Key.
  6. - *
  7. Derives the symmetric Content - * Encryption {@code SecretKey} with the Concat KDF algorithm using the - * obtained shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. - *
  9. Returns the derived symmetric {@code SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. - *
- */ - public static final KeyAlgorithm ECDH_ES = Jwts.get(REGISTRY, "ECDH-ES"); - - /** - * Key Agreement with Key Wrapping via - * ECDH-ES using Concat KDF and CEK wrapped with "A128KW" as defined by - * RFC 7518 (JWA), Section 4.6. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the - * JWE recipient's EC Public Key.
  2. - *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key - * and the JWE recipient's EC Public Key.
  4. - *
  5. Derives a 128-bit symmetric Key - * Encryption {@code SecretKey} with the Concat KDF algorithm using the - * generated shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. - *
  7. Sets the generated EC key pair's Public Key as the required - * "epk" - * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. - *
  9. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  10. - *
  11. 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.
  12. - *
  13. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  14. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the - * "epk" - * (Ephemeral Public Key) Header Parameter.
  2. - *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. - *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key - * and the JWE recipient's EC Private Key.
  6. - *
  7. Derives the symmetric Key - * Encryption {@code SecretKey} with the Concat KDF algorithm using the - * obtained shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. - *
  9. Obtains the encrypted key ciphertext embedded in the received JWE.
  10. - *
  11. Decrypts the encrypted key ciphertext with the AES Key Unwrap algorithm using the - * 128-bit derived symmetric key from step {@code #4}, producing the decryption key plaintext.
  12. - *
  13. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  14. - *
- */ - public static final KeyAlgorithm ECDH_ES_A128KW = Jwts.get(REGISTRY, "ECDH-ES+A128KW"); - - /** - * Key Agreement with Key Wrapping via - * ECDH-ES using Concat KDF and CEK wrapped with "A192KW" as defined by - * RFC 7518 (JWA), Section 4.6. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the - * JWE recipient's EC Public Key.
  2. - *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key - * and the JWE recipient's EC Public Key.
  4. - *
  5. Derives a 192-bit symmetric Key - * Encryption {@code SecretKey} with the Concat KDF algorithm using the - * generated shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. - *
  7. Sets the generated EC key pair's Public Key as the required - * "epk" - * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. - *
  9. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  10. - *
  11. 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.
  12. - *
  13. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  14. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the - * "epk" - * (Ephemeral Public Key) Header Parameter.
  2. - *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. - *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key - * and the JWE recipient's EC Private Key.
  6. - *
  7. Derives the 192-bit symmetric - * Key Encryption {@code SecretKey} with the Concat KDF algorithm using the - * obtained shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. - *
  9. Obtains the encrypted key ciphertext embedded in the received JWE.
  10. - *
  11. Decrypts the encrypted key ciphertext with the AES Key Unwrap algorithm using the - * 192-bit derived symmetric key from step {@code #4}, producing the decryption key plaintext.
  12. - *
  13. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  14. - *
- */ - public static final KeyAlgorithm ECDH_ES_A192KW = Jwts.get(REGISTRY, "ECDH-ES+A192KW"); - - /** - * Key Agreement with Key Wrapping via - * ECDH-ES using Concat KDF and CEK wrapped with "A256KW" as defined by - * RFC 7518 (JWA), Section 4.6. - * - *

During JWE creation, this algorithm:

- *
    - *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the - * JWE recipient's EC Public Key.
  2. - *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key - * and the JWE recipient's EC Public Key.
  4. - *
  5. Derives a 256-bit symmetric Key - * Encryption {@code SecretKey} with the Concat KDF algorithm using the - * generated shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. - *
  7. Sets the generated EC key pair's Public Key as the required - * "epk" - * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. - *
  9. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a - * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  10. - *
  11. 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.
  12. - *
  13. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated - * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  14. - *
- *

For JWE decryption, this algorithm:

- *
    - *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the - * "epk" - * (Ephemeral Public Key) Header Parameter.
  2. - *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. - *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key - * and the JWE recipient's EC Private Key.
  6. - *
  7. Derives the 256-bit symmetric - * Key Encryption {@code SecretKey} with the Concat KDF algorithm using the - * obtained shared secret and any available - * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and - * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. - *
  9. Obtains the encrypted key ciphertext embedded in the received JWE.
  10. - *
  11. Decrypts the encrypted key ciphertext with the AES Key Unwrap algorithm using the - * 256-bit derived symmetric key from step {@code #4}, producing the decryption key plaintext.
  12. - *
  13. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire - * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  14. - *
- */ - public static final KeyAlgorithm ECDH_ES_A256KW = Jwts.get(REGISTRY, "ECDH-ES+A256KW"); - - //prevent instantiation - private KEY() { - } + public static JwsHeader jwsHeader() { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwsHeader"); } /** - * Constants for JWA (RFC 7518) compression algorithms referenced in the {@code zip} header defined in the - * JSON Web Encryption Compression Algorithms - * Registry. Each algorithm is available as a ({@code public static final}) constant for - * direct type-safe reference in application code. For example: - *
-     * Jwts.builder()
-     *    // ... etc ...
-     *    .compressWith(Jwts.ZIP.DEF)
-     *    .build();
- *

They are also available together as a {@link Registry} instance via the {@link #get()} method.

+ * Returns a new {@link JwsHeader} instance suitable for digitally signed JWTs (aka 'JWS's), populated with the + * specified name/value pairs. * - * @see #get() - * @since 0.12.0 + * @return a new {@link JwsHeader} instance suitable for digitally signed JWTs (aka 'JWS's), populated with the + * specified name/value pairs. + * @see JwtBuilder#setHeader(Header) */ - public static final class ZIP { - - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.io.StandardCompressionAlgorithms"; - private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - - /** - * Returns various useful - * Compression Algorithms. - * - * @return various standard and non-standard useful compression algorithms. - */ - public static Registry get() { - return REGISTRY; - } - - /** - * The JWE-standard DEFLATE - * compression algorithm with a {@code zip} header value of {@code "DEF"}. - * - * @see JWE RFC 7516, Section 4.1.3 - */ - public static final CompressionAlgorithm DEF = get().forKey("DEF"); - - /** - * A commonly used, but NOT JWA-STANDARD - * gzip compression algorithm with a {@code zip} header value - * of {@code "GZIP"}. - * - *

Compatibility Warning

- * - *

This is not a standard JWE compression algorithm. Be sure to use this only when you are confident - * that all parties accessing the token support the "GZIP" identifier and associated algorithm.

- * - *

If you're concerned about compatibility, {@link #DEF DEF} is the only JWA standards-compliant algorithm.

- * - * @see #DEF - */ - public static final CompressionAlgorithm GZIP = get().forKey("GZIP"); - - //prevent instantiation - private ZIP() { - } + public static JwsHeader jwsHeader(Map header) { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwsHeader", MAP_ARG, header); } /** - * A {@link Builder} that dynamically determines the type of {@link Header} to create based on builder state. + * Returns a new {@link Claims} instance to be used as a JWT body. * - * @since 0.12.0 + * @return a new {@link Claims} instance to be used as a JWT body. */ - public interface HeaderBuilder extends JweHeaderMutator, X509Builder, Builder
{ + public static Claims claims() { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultClaims"); } /** - * Returns a new {@link HeaderBuilder} that can build any type of {@link Header} instance depending on - * which builder properties are set. + * Returns a new {@link Claims} instance populated with the specified name/value pairs. * - * @return a new {@link HeaderBuilder} that can build any type of {@link Header} instance depending on - * which builder properties are set. - * @since 0.12.0 + * @param claims the name/value pairs to populate the new Claims instance. + * @return a new {@link Claims} instance populated with the specified name/value pairs. */ - public static HeaderBuilder header() { - return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtHeaderBuilder"); + public static Claims claims(Map claims) { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultClaims", MAP_ARG, claims); } /** - * Returns a new {@link Claims} builder instance to be used to populate JWT claims, which in aggregate will be - * the JWT payload. + * Returns a new {@link JwtParser} instance that can be configured and then used to parse JWT strings. * - * @return a new {@link Claims} builder instance to be used to populate JWT claims, which in aggregate will be - * the JWT payload. + * @return a new {@link JwtParser} instance that can be configured and then used to parse JWT strings. + * @deprecated use {@link Jwts#parserBuilder()} instead. See {@link JwtParserBuilder} for usage details. + *

Migration to new method structure is minimal, for example: + *

Old code: + *

{@code
+     *     Jwts.parser()
+     *         .requireAudience("string")
+     *         .parse(jwtString)
+     * }
+ *

New code: + *

{@code
+     *     Jwts.parserBuilder()
+     *         .requireAudience("string")
+     *         .build()
+     *         .parse(jwtString)
+     * }
+ *

NOTE: this method will be removed before version 1.0 */ - public static ClaimsBuilder claims() { - return Classes.newInstance("io.jsonwebtoken.impl.DefaultClaimsBuilder"); + @Deprecated + public static JwtParser parser() { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParser"); } /** - *

Deprecated since 0.12.0 in favor of - * {@code Jwts.}{@link #claims()}{@code .add(map).build()}. - * This method will be removed before 1.0.

+ * Returns a new {@link JwtParserBuilder} instance that can be configured to create an immutable/thread-safe {@link JwtParser). * - *

Returns a new {@link Claims} instance populated with the specified name/value pairs.

- * - * @param claims the name/value pairs to populate the new Claims instance. - * @return a new {@link Claims} instance populated with the specified name/value pairs. - * @deprecated since 0.12.0 in favor of {@code Jwts.}{@link #claims()}{@code .putAll(map).build()}. - * This method will be removed before 1.0. + * @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser). */ - @Deprecated - public static Claims claims(Map claims) { - return claims().add(claims).build(); + public static JwtParserBuilder parserBuilder() { + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParserBuilder"); } /** @@ -1059,19 +140,4 @@ public static JwtBuilder builder() { 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. - */ - private Jwts() { - } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/Locator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/LocatorAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/MalformedJwtException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/MalformedJwtException.java (.../MalformedJwtException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/MalformedJwtException.java (.../MalformedJwtException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,21 +22,10 @@ */ public class MalformedJwtException extends JwtException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public MalformedJwtException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public MalformedJwtException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/MissingClaimException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/MissingClaimException.java (.../MissingClaimException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/MissingClaimException.java (.../MissingClaimException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,34 +22,11 @@ * @since 0.6 */ public class MissingClaimException extends InvalidClaimException { - - /** - * Creates a new instance with the specified explanation message. - * - * @param header the header associated with the claims that did not contain the required claim - * @param claims the claims that did not contain the required claim - * @param claimName the name of the claim that could not be validated - * @param claimValue the value of the claim that could not be validated - * @param message the message explaining why the exception is thrown. - */ - public MissingClaimException(Header header, Claims claims, String claimName, Object claimValue, String message) { - super(header, claims, claimName, claimValue, message); + public MissingClaimException(Header header, Claims claims, String message) { + super(header, claims, message); } - - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param header the header associated with the claims that did not contain the required claim - * @param claims the claims that did not contain the required claim - * @param claimName the name of the claim that could not be validated - * @param claimValue the value of the claim that could not be validated - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - * @deprecated since 0.12.0 since it is not used in JJWT's codebase - */ - @Deprecated - public MissingClaimException(Header header, Claims claims, String claimName, Object claimValue, String message, Throwable cause) { - super(header, claims, claimName, claimValue, message, cause); + public MissingClaimException(Header header, Claims claims, String message, Throwable cause) { + super(header, claims, message, cause); } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/PrematureJwtException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/PrematureJwtException.java (.../PrematureJwtException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/PrematureJwtException.java (.../PrematureJwtException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,28 +22,17 @@ */ public class PrematureJwtException extends ClaimJwtException { - /** - * Creates a new instance with the specified explanation message. - * - * @param header jwt header - * @param claims jwt claims (body) - * @param message the message explaining why the exception is thrown. - */ public PrematureJwtException(Header header, Claims claims, String message) { super(header, claims, message); } /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param header jwt header - * @param claims jwt claims (body) + * @param header jwt header + * @param claims jwt claims (body) * @param message exception message - * @param cause cause + * @param cause cause * @since 0.5 - * @deprecated since 0.12.0 since it is not used in JJWT's codebase */ - @Deprecated public PrematureJwtException(Header header, Claims claims, String message, Throwable cause) { super(header, claims, message, cause); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ProtectedHeader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ProtectedHeaderMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/ProtectedJwt.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/RequiredTypeException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/RequiredTypeException.java (.../RequiredTypeException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/RequiredTypeException.java (.../RequiredTypeException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,28 +16,16 @@ package io.jsonwebtoken; /** - * Exception thrown when attempting to obtain a value from a JWT or JWK and the existing value does not match the - * expected type. + * Exception thrown when {@link Claims#get(String, Class)} is called and the value does not match the type of the + * {@code Class} argument. * * @since 0.6 */ public class RequiredTypeException extends JwtException { - - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public RequiredTypeException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public RequiredTypeException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SignatureAlgorithm.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SignatureAlgorithm.java (.../SignatureAlgorithm.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SignatureAlgorithm.java (.../SignatureAlgorithm.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -34,9 +34,7 @@ * JSON Web Algorithms specification. * * @since 0.1 - * @deprecated since 0.12.0; use {@link Jwts.SIG} instead. */ -@Deprecated public enum SignatureAlgorithm { /** @@ -112,10 +110,10 @@ //purposefully ordered higher to lower: private static final List PREFERRED_HMAC_ALGS = Collections.unmodifiableList(Arrays.asList( - SignatureAlgorithm.HS512, SignatureAlgorithm.HS384, SignatureAlgorithm.HS256)); + SignatureAlgorithm.HS512, SignatureAlgorithm.HS384, SignatureAlgorithm.HS256)); //purposefully ordered higher to lower: private static final List PREFERRED_EC_ALGS = Collections.unmodifiableList(Arrays.asList( - SignatureAlgorithm.ES512, SignatureAlgorithm.ES384, SignatureAlgorithm.ES256)); + SignatureAlgorithm.ES512, SignatureAlgorithm.ES384, SignatureAlgorithm.ES256)); private final String value; private final String description; @@ -134,7 +132,7 @@ SignatureAlgorithm(String value, String description, String familyName, String jcaName, boolean jdkStandard, int digestLength, int minKeyLength) { - this(value, description, familyName, jcaName, jdkStandard, digestLength, minKeyLength, jcaName); + this(value, description,familyName, jcaName, jdkStandard, digestLength, minKeyLength, jcaName); } SignatureAlgorithm(String value, String description, String familyName, String jcaName, boolean jdkStandard, @@ -367,25 +365,25 @@ // These next checks use equalsIgnoreCase per https://github.com/jwtk/jjwt/issues/381#issuecomment-412912272 if (!HS256.jcaName.equalsIgnoreCase(alg) && - !HS384.jcaName.equalsIgnoreCase(alg) && - !HS512.jcaName.equalsIgnoreCase(alg) && - !HS256.pkcs12Name.equals(alg) && - !HS384.pkcs12Name.equals(alg) && - !HS512.pkcs12Name.equals(alg)) { + !HS384.jcaName.equalsIgnoreCase(alg) && + !HS512.jcaName.equalsIgnoreCase(alg) && + !HS256.pkcs12Name.equals(alg) && + !HS384.pkcs12Name.equals(alg) && + !HS512.pkcs12Name.equals(alg)) { throw new InvalidKeyException("The " + keyType(signing) + " key's algorithm '" + alg + - "' does not equal a valid HmacSHA* algorithm name and cannot be used with " + name() + "."); + "' does not equal a valid HmacSHA* algorithm name and cannot be used with " + name() + "."); } int size = encoded.length * 8; //size in bits if (size < this.minKeyLength) { String msg = "The " + keyType(signing) + " key's size is " + size + " bits which " + - "is not secure enough for the " + name() + " algorithm. The JWT " + - "JWA Specification (RFC 7518, Section 3.2) states that keys used with " + name() + " MUST have a " + - "size >= " + minKeyLength + " bits (the key size must be greater than or equal to the hash " + - "output size). Consider using the " + Keys.class.getName() + " class's " + - "'secretKeyFor(SignatureAlgorithm." + name() + ")' method to create a key guaranteed to be " + - "secure enough for " + name() + ". See " + - "https://tools.ietf.org/html/rfc7518#section-3.2 for more information."; + "is not secure enough for the " + name() + " algorithm. The JWT " + + "JWA Specification (RFC 7518, Section 3.2) states that keys used with " + name() + " MUST have a " + + "size >= " + minKeyLength + " bits (the key size must be greater than or equal to the hash " + + "output size). Consider using the " + Keys.class.getName() + " class's " + + "'secretKeyFor(SignatureAlgorithm." + name() + ")' method to create a key guaranteed to be " + + "secure enough for " + name() + ". See " + + "https://tools.ietf.org/html/rfc7518#section-3.2 for more information."; throw new WeakKeyException(msg); } @@ -409,13 +407,13 @@ int size = ecKey.getParams().getOrder().bitLength(); if (size < this.minKeyLength) { String msg = "The " + keyType(signing) + " key's size (ECParameterSpec order) is " + size + - " bits which is not secure enough for the " + name() + " algorithm. The JWT " + - "JWA Specification (RFC 7518, Section 3.4) states that keys used with " + - name() + " MUST have a size >= " + this.minKeyLength + - " bits. Consider using the " + Keys.class.getName() + " class's " + - "'keyPairFor(SignatureAlgorithm." + name() + ")' method to create a key pair guaranteed " + - "to be secure enough for " + name() + ". See " + - "https://tools.ietf.org/html/rfc7518#section-3.4 for more information."; + " bits which is not secure enough for the " + name() + " algorithm. The JWT " + + "JWA Specification (RFC 7518, Section 3.4) states that keys used with " + + name() + " MUST have a size >= " + this.minKeyLength + + " bits. Consider using the " + Keys.class.getName() + " class's " + + "'keyPairFor(SignatureAlgorithm." + name() + ")' method to create a key pair guaranteed " + + "to be secure enough for " + name() + ". See " + + "https://tools.ietf.org/html/rfc7518#section-3.4 for more information."; throw new WeakKeyException(msg); } @@ -433,12 +431,12 @@ String section = name().startsWith("P") ? "3.5" : "3.3"; String msg = "The " + keyType(signing) + " key's size is " + size + " bits which is not secure " + - "enough for the " + name() + " algorithm. The JWT JWA Specification (RFC 7518, Section " + - section + ") states that keys used with " + name() + " MUST have a size >= " + - this.minKeyLength + " bits. Consider using the " + Keys.class.getName() + " class's " + - "'keyPairFor(SignatureAlgorithm." + name() + ")' method to create a key pair guaranteed " + - "to be secure enough for " + name() + ". See " + - "https://tools.ietf.org/html/rfc7518#section-" + section + " for more information."; + "enough for the " + name() + " algorithm. The JWT JWA Specification (RFC 7518, Section " + + section + ") states that keys used with " + name() + " MUST have a size >= " + + this.minKeyLength + " bits. Consider using the " + Keys.class.getName() + " class's " + + "'keyPairFor(SignatureAlgorithm." + name() + ")' method to create a key pair guaranteed " + + "to be secure enough for " + name() + ". See " + + "https://tools.ietf.org/html/rfc7518#section-" + section + " for more information."; throw new WeakKeyException(msg); } } @@ -533,7 +531,7 @@ * Section 3.3) mandates that RSA signing key lengths MUST be 2048 bits or greater. * {@code RSAKey}s with key lengths less than 2048 bits will be rejected with a * {@link WeakKeyException}. - *
  • Technically any RSA key of length >= 2048 bits may be used with the {@link #RS256}, {@link #RS384}, and + *
  • Technically any RSA key of length >= 2048 bits may be used with the {@link #RS256}, {@link #RS384}, and * {@link #RS512} algorithms, so we assume an RSA signature algorithm based on the key length to * parallel similar decisions in the JWT specification for HMAC and ECDSA signature algorithms. * This is not required - just a convenience.
  • @@ -547,6 +545,7 @@ *
  • The {@link #RS256}, {@link #RS384}, and {@link #RS512} algorithms are available in the JDK by default * while the {@code PS}* variants require an additional JCA Provider (like BouncyCastle).
  • * + *

    * *

    Finally, this method will throw an {@link InvalidKeyException} for any key that does not match the * heuristics and requirements documented above, since that inevitably means the Key is either insufficient or @@ -565,29 +564,29 @@ } if (!(key instanceof SecretKey || - (key instanceof PrivateKey && (key instanceof ECKey || key instanceof RSAKey)))) { + (key instanceof PrivateKey && (key instanceof ECKey || key instanceof RSAKey)))) { String msg = "JWT standard signing algorithms require either 1) a SecretKey for HMAC-SHA algorithms or " + - "2) a private RSAKey for RSA algorithms or 3) a private ECKey for Elliptic Curve algorithms. " + - "The specified key is of type " + key.getClass().getName(); + "2) a private RSAKey for RSA algorithms or 3) a private ECKey for Elliptic Curve algorithms. " + + "The specified key is of type " + key.getClass().getName(); throw new InvalidKeyException(msg); } if (key instanceof SecretKey) { - SecretKey secretKey = (SecretKey) key; + SecretKey secretKey = (SecretKey)key; int bitLength = io.jsonwebtoken.lang.Arrays.length(secretKey.getEncoded()) * Byte.SIZE; - for (SignatureAlgorithm alg : PREFERRED_HMAC_ALGS) { + for(SignatureAlgorithm alg : PREFERRED_HMAC_ALGS) { // ensure compatibility check is based on key length. See https://github.com/jwtk/jjwt/issues/381 if (bitLength >= alg.minKeyLength) { return alg; } } String msg = "The specified SecretKey is not strong enough to be used with JWT HMAC signature " + - "algorithms. The JWT specification requires HMAC keys to be >= 256 bits long. The specified " + - "key is " + bitLength + " bits. See https://tools.ietf.org/html/rfc7518#section-3.2 for more " + - "information."; + "algorithms. The JWT specification requires HMAC keys to be >= 256 bits long. The specified " + + "key is " + bitLength + " bits. See https://tools.ietf.org/html/rfc7518#section-3.2 for more " + + "information."; throw new WeakKeyException(msg); } @@ -608,9 +607,9 @@ } String msg = "The specified RSA signing key is not strong enough to be used with JWT RSA signature " + - "algorithms. The JWT specification requires RSA keys to be >= 2048 bits long. The specified RSA " + - "key is " + bitLength + " bits. See https://tools.ietf.org/html/rfc7518#section-3.3 for more " + - "information."; + "algorithms. The JWT specification requires RSA keys to be >= 2048 bits long. The specified RSA " + + "key is " + bitLength + " bits. See https://tools.ietf.org/html/rfc7518#section-3.3 for more " + + "information."; throw new WeakKeyException(msg); } @@ -628,9 +627,9 @@ } String msg = "The specified Elliptic Curve signing key is not strong enough to be used with JWT ECDSA " + - "signature algorithms. The JWT specification requires ECDSA keys to be >= 256 bits long. " + - "The specified ECDSA key is " + bitLength + " bits. See " + - "https://tools.ietf.org/html/rfc7518#section-3.4 for more information."; + "signature algorithms. The JWT specification requires ECDSA keys to be >= 256 bits long. " + + "The specified ECDSA key is " + bitLength + " bits. See " + + "https://tools.ietf.org/html/rfc7518#section-3.4 for more information."; throw new WeakKeyException(msg); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SignatureException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SignatureException.java (.../SignatureException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SignatureException.java (.../SignatureException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -21,26 +21,15 @@ * Exception indicating that either calculating a signature or verifying an existing signature of a JWT failed. * * @since 0.1 - * @deprecated in favor of {@link io.jsonwebtoken.security.SignatureException}; this class will be removed before 1.0 + * @deprecated in favor of {@link io.jsonwebtoken.security.SecurityException}; this class will be removed before 1.0 */ @Deprecated public class SignatureException extends SecurityException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public SignatureException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public SignatureException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SigningKeyResolver.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SigningKeyResolver.java (.../SigningKeyResolver.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SigningKeyResolver.java (.../SigningKeyResolver.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,7 +22,7 @@ * should be used to verify a JWS signature. * *

    A {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing the JWT and the - * JWT header or payload (byte array or Claims) must be inspected first to determine how to look up the signing key. + * JWT header or payload (plaintext body or Claims) must be inspected first to determine how to look up the signing key. * Once returned by the resolver, the JwtParser will then verify the JWS signature with the returned key. For * example:

    * @@ -33,43 +33,41 @@ * //inspect the header or claims, lookup and return the signing key * return getSigningKeyBytes(header, claims); //implement me * }}) - * .build().parseSignedClaims(compact); + * .parseClaimsJws(compact); * * *

    A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.

    * - *

    Using an Adapter

    + *

    SigningKeyResolverAdapter

    * - *

    If you only need to resolve a signing key for a particular JWS (either a content or Claims JWS), consider using + *

    If you only need to resolve a signing key for a particular JWS (either a plaintext or Claims JWS), consider using * the {@link io.jsonwebtoken.SigningKeyResolverAdapter} and overriding only the method you need to support instead of * implementing this interface directly.

    * - * @see io.jsonwebtoken.JwtParserBuilder#keyLocator(Locator) + * @see io.jsonwebtoken.SigningKeyResolverAdapter * @since 0.4 - * @deprecated since 0.12.0. Implement {@link Locator} instead. */ -@Deprecated public interface SigningKeyResolver { /** * Returns the signing key that should be used to validate a digital signature for the Claims JWS with the specified * header and claims. * * @param header the header of the JWS to validate - * @param claims the Claims payload of the JWS to validate + * @param claims the claims (body) of the JWS to validate * @return the signing key that should be used to validate a digital signature for the Claims JWS with the specified * header and claims. */ Key resolveSigningKey(JwsHeader header, Claims claims); /** - * Returns the signing key that should be used to validate a digital signature for the content JWS with the - * specified header and byte array payload. + * Returns the signing key that should be used to validate a digital signature for the Plaintext JWS with the + * specified header and plaintext payload. * - * @param header the header of the JWS to validate - * @param content the byte array payload of the JWS to validate - * @return the signing key that should be used to validate a digital signature for the content JWS with the - * specified header and byte array payload. + * @param header the header of the JWS to validate + * @param plaintext the plaintext body of the JWS to validate + * @return the signing key that should be used to validate a digital signature for the Plaintext JWS with the + * specified header and plaintext payload. */ - Key resolveSigningKey(JwsHeader header, byte[] content); + Key resolveSigningKey(JwsHeader header, String plaintext); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SigningKeyResolverAdapter.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SigningKeyResolverAdapter.java (.../SigningKeyResolverAdapter.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SigningKeyResolverAdapter.java (.../SigningKeyResolverAdapter.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -21,67 +21,44 @@ import java.security.Key; /** - *

    Deprecation Notice

    - * - *

    As of JJWT 0.12.0, 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#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. This {@code SigningKeyResolverAdapter} class will be removed before the 1.0 release.

    - * - *

    Previous Documentation

    - * - *

    An Adapter implementation of the + * An Adapter implementation of the * {@link SigningKeyResolver} interface that allows subclasses to process only the type of JWS body that - * is known/expected for a particular case.

    + * is known/expected for a particular case. * - *

    The {@link #resolveSigningKey(JwsHeader, Claims)} and {@link #resolveSigningKey(JwsHeader, byte[])} method + *

    The {@link #resolveSigningKey(JwsHeader, Claims)} and {@link #resolveSigningKey(JwsHeader, String)} method * implementations delegate to the - * {@link #resolveSigningKeyBytes(JwsHeader, Claims)} and {@link #resolveSigningKeyBytes(JwsHeader, byte[])} methods + * {@link #resolveSigningKeyBytes(JwsHeader, Claims)} and {@link #resolveSigningKeyBytes(JwsHeader, String)} methods * respectively. The latter two methods simply throw exceptions: they represent scenarios expected by * calling code in known situations, and it is expected that you override the implementation in those known situations; * non-overridden *KeyBytes methods indicates that the JWS input was unexpected.

    * - *

    If either {@link #resolveSigningKey(JwsHeader, byte[])} or {@link #resolveSigningKey(JwsHeader, Claims)} + *

    If either {@link #resolveSigningKey(JwsHeader, String)} or {@link #resolveSigningKey(JwsHeader, Claims)} * 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.

    * - * @see io.jsonwebtoken.JwtParserBuilder#keyLocator(Locator) - * @see LocatorAdapter * @since 0.4 - * @deprecated since 0.12.0. Use {@link LocatorAdapter LocatorAdapter} with - * {@link JwtParserBuilder#keyLocator(Locator)} */ -@SuppressWarnings("DeprecatedIsStillUsed") -@Deprecated public class SigningKeyResolverAdapter implements SigningKeyResolver { - /** - * Default constructor. - */ - public SigningKeyResolverAdapter() { - - } - @Override public Key resolveSigningKey(JwsHeader header, Claims claims) { SignatureAlgorithm alg = SignatureAlgorithm.forName(header.getAlgorithm()); - Assert.isTrue(alg.isHmac(), "The default resolveSigningKey(JwsHeader, Claims) implementation cannot " + - "be used for asymmetric key algorithms (RSA, Elliptic Curve). " + - "Override the resolveSigningKey(JwsHeader, Claims) method instead and return a " + - "Key instance appropriate for the " + alg.name() + " algorithm."); + Assert.isTrue(alg.isHmac(), "The default resolveSigningKey(JwsHeader, Claims) implementation cannot be " + + "used for asymmetric key algorithms (RSA, Elliptic Curve). " + + "Override the resolveSigningKey(JwsHeader, Claims) method instead and return a " + + "Key instance appropriate for the " + alg.name() + " algorithm."); byte[] keyBytes = resolveSigningKeyBytes(header, claims); return new SecretKeySpec(keyBytes, alg.getJcaName()); } @Override - public Key resolveSigningKey(JwsHeader header, byte[] content) { + public Key resolveSigningKey(JwsHeader header, String plaintext) { SignatureAlgorithm alg = SignatureAlgorithm.forName(header.getAlgorithm()); - Assert.isTrue(alg.isHmac(), "The default resolveSigningKey(JwsHeader, byte[]) implementation cannot " + - "be used for asymmetric key algorithms (RSA, Elliptic Curve). " + - "Override the resolveSigningKey(JwsHeader, byte[]) method instead and return a " + - "Key instance appropriate for the " + alg.name() + " algorithm."); - byte[] keyBytes = resolveSigningKeyBytes(header, content); + Assert.isTrue(alg.isHmac(), "The default resolveSigningKey(JwsHeader, String) implementation cannot be " + + "used for asymmetric key algorithms (RSA, Elliptic Curve). " + + "Override the resolveSigningKey(JwsHeader, String) method instead and return a " + + "Key instance appropriate for the " + alg.name() + " algorithm."); + byte[] keyBytes = resolveSigningKeyBytes(header, plaintext); return new SecretKeySpec(keyBytes, alg.getJcaName()); } @@ -99,25 +76,24 @@ */ public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { throw new UnsupportedJwtException("The specified SigningKeyResolver implementation does not support " + - "Claims JWS signing key resolution. Consider overriding either the " + - "resolveSigningKey(JwsHeader, Claims) method or, for HMAC algorithms, the " + - "resolveSigningKeyBytes(JwsHeader, Claims) method."); + "Claims JWS signing key resolution. Consider overriding either the " + + "resolveSigningKey(JwsHeader, Claims) method or, for HMAC algorithms, the " + + "resolveSigningKeyBytes(JwsHeader, Claims) method."); } /** - * Convenience method invoked by {@link #resolveSigningKey(JwsHeader, byte[])} that obtains the necessary signing - * key bytes. This implementation simply throws an exception: if the JWS parsed is a content JWS, you must - * override this method or the {@link #resolveSigningKey(JwsHeader, byte[])} method instead. + * Convenience method invoked by {@link #resolveSigningKey(JwsHeader, String)} that obtains the necessary signing + * key bytes. This implementation simply throws an exception: if the JWS parsed is a plaintext JWS, you must + * override this method or the {@link #resolveSigningKey(JwsHeader, String)} method instead. * - * @param header the parsed {@link JwsHeader} - * @param content the byte array payload + * @param header the parsed {@link JwsHeader} + * @param payload the parsed String plaintext payload * @return the signing key bytes to use to verify the JWS signature. */ - @SuppressWarnings("unused") - public byte[] resolveSigningKeyBytes(JwsHeader header, byte[] content) { + public byte[] resolveSigningKeyBytes(JwsHeader header, String payload) { throw new UnsupportedJwtException("The specified SigningKeyResolver implementation does not support " + - "content JWS signing key resolution. Consider overriding either the " + - "resolveSigningKey(JwsHeader, byte[]) method or, for HMAC algorithms, the " + - "resolveSigningKeyBytes(JwsHeader, byte[]) method."); + "plaintext JWS signing key resolution. Consider overriding either the " + + "resolveSigningKey(JwsHeader, String) method or, for HMAC algorithms, the " + + "resolveSigningKeyBytes(JwsHeader, String) method."); } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/SupportedJwtVisitor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/UnsupportedJwtException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/UnsupportedJwtException.java (.../UnsupportedJwtException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/UnsupportedJwtException.java (.../UnsupportedJwtException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -19,28 +19,17 @@ * Exception thrown when receiving a JWT in a particular format/configuration that does not match the format expected * by the application. * - *

    For example, this exception would be thrown if parsing an unprotected content JWT when the application + *

    For example, this exception would be thrown if parsing an unsigned plaintext JWT when the application * requires a cryptographically signed Claims JWS instead.

    * * @since 0.2 */ public class UnsupportedJwtException extends JwtException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public UnsupportedJwtException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public UnsupportedJwtException(String message, Throwable cause) { super(message, cause); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/AbstractAudienceCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/AbstractX509Context.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/CompressionCodecLocator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultClaims.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultClaims.java (.../DefaultClaims.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultClaims.java (.../DefaultClaims.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,137 +17,154 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.RequiredTypeException; -import io.jsonwebtoken.impl.lang.JwtDateConverter; -import io.jsonwebtoken.impl.lang.Parameter; -import io.jsonwebtoken.impl.lang.Parameters; -import io.jsonwebtoken.lang.Assert; -import io.jsonwebtoken.lang.Registry; - import java.util.Date; import java.util.Map; -import java.util.Set; -public class DefaultClaims extends ParameterMap implements Claims { +public class DefaultClaims extends JwtMap implements Claims { private static final String CONVERSION_ERROR_MSG = "Cannot convert existing claim value of type '%s' to desired type " + "'%s'. JJWT only converts simple String, Date, Long, Integer, Short and Byte types automatically. " + "Anything more complex is expected to be already converted to your desired type by the JSON Deserializer " + "implementation. You may specify a custom Deserializer for a JwtParser with the desired conversion " + - "configuration via the JwtParserBuilder.deserializer() method. " + + "configuration via the JwtParserBuilder.deserializeJsonWith() method. " + "See https://github.com/jwtk/jjwt#custom-json-processor for more information. If using Jackson, you can " + "specify custom claim POJO types as described in https://github.com/jwtk/jjwt#json-jackson-custom-types"; - static final Parameter ISSUER = Parameters.string(Claims.ISSUER, "Issuer"); - static final Parameter SUBJECT = Parameters.string(Claims.SUBJECT, "Subject"); - static final Parameter> AUDIENCE = Parameters.stringSet(Claims.AUDIENCE, "Audience"); - static final Parameter EXPIRATION = Parameters.rfcDate(Claims.EXPIRATION, "Expiration Time"); - static final Parameter NOT_BEFORE = Parameters.rfcDate(Claims.NOT_BEFORE, "Not Before"); - static final Parameter ISSUED_AT = Parameters.rfcDate(Claims.ISSUED_AT, "Issued At"); - static final Parameter JTI = Parameters.string(Claims.ID, "JWT ID"); + public DefaultClaims() { + super(); + } - static final Registry> PARAMS = - Parameters.registry(ISSUER, SUBJECT, AUDIENCE, EXPIRATION, NOT_BEFORE, ISSUED_AT, JTI); - - protected DefaultClaims() { // visibility for testing - super(PARAMS); + public DefaultClaims(Map map) { + super(map); } - public DefaultClaims(ParameterMap m) { - super(m.PARAMS, m); + @Override + public String getIssuer() { + return getString(ISSUER); } - public DefaultClaims(Map map) { - super(PARAMS, map); + @Override + public Claims setIssuer(String iss) { + setValue(ISSUER, iss); + return this; } @Override - public String getName() { - return "JWT Claims"; + public String getSubject() { + return getString(SUBJECT); } @Override - public String getIssuer() { - return get(ISSUER); + public Claims setSubject(String sub) { + setValue(SUBJECT, sub); + return this; } @Override - public String getSubject() { - return get(SUBJECT); + public String getAudience() { + return getString(AUDIENCE); } @Override - public Set getAudience() { - return get(AUDIENCE); + public Claims setAudience(String aud) { + setValue(AUDIENCE, aud); + return this; } @Override public Date getExpiration() { - return get(EXPIRATION); + return get(Claims.EXPIRATION, Date.class); } @Override + public Claims setExpiration(Date exp) { + setDateAsSeconds(Claims.EXPIRATION, exp); + return this; + } + + @Override public Date getNotBefore() { - return get(NOT_BEFORE); + return get(Claims.NOT_BEFORE, Date.class); } @Override + public Claims setNotBefore(Date nbf) { + setDateAsSeconds(Claims.NOT_BEFORE, nbf); + return this; + } + + @Override public Date getIssuedAt() { - return get(ISSUED_AT); + return get(Claims.ISSUED_AT, Date.class); } @Override + public Claims setIssuedAt(Date iat) { + setDateAsSeconds(Claims.ISSUED_AT, iat); + return this; + } + + @Override public String getId() { - return get(JTI); + return getString(ID); } @Override - public T get(String claimName, Class requiredType) { - Assert.notNull(requiredType, "requiredType argument cannot be null."); + public Claims setId(String jti) { + setValue(Claims.ID, jti); + return this; + } - Object value = this.idiomaticValues.get(claimName); - if (requiredType.isInstance(value)) { - return requiredType.cast(value); + /** + * @since 0.10.0 + */ + private static boolean isSpecDate(String claimName) { + return Claims.EXPIRATION.equals(claimName) || + Claims.ISSUED_AT.equals(claimName) || + Claims.NOT_BEFORE.equals(claimName); + } + + @Override + public Object put(String s, Object o) { + if (o instanceof Date && isSpecDate(s)) { //since 0.10.0 + Date date = (Date)o; + return setDateAsSeconds(s, date); } + return super.put(s, o); + } - value = get(claimName); + @Override + public T get(String claimName, Class requiredType) { + + Object value = get(claimName); if (value == null) { return null; } if (Date.class.equals(requiredType)) { - try { - value = JwtDateConverter.toDate(value); // NOT specDate logic - } catch (Exception e) { - String msg = "Cannot create Date from '" + claimName + "' value '" + value + "'. Cause: " + e.getMessage(); - throw new IllegalArgumentException(msg, e); + if (isSpecDate(claimName)) { + value = toSpecDate(value, claimName); + } else { + value = toDate(value, claimName); } } - return castClaimValue(claimName, value, requiredType); + return castClaimValue(value, requiredType); } - private T castClaimValue(String name, Object value, Class requiredType) { + private T castClaimValue(Object value, Class requiredType) { - if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte) { - long longValue = ((Number) value).longValue(); - if (Long.class.equals(requiredType)) { - value = longValue; - } else if (Integer.class.equals(requiredType) && Integer.MIN_VALUE <= longValue && longValue <= Integer.MAX_VALUE) { - value = (int) longValue; - } else if (requiredType == Short.class && Short.MIN_VALUE <= longValue && longValue <= Short.MAX_VALUE) { - value = (short) longValue; - } else if (requiredType == Byte.class && Byte.MIN_VALUE <= longValue && longValue <= Byte.MAX_VALUE) { - value = (byte) longValue; + if (value instanceof Integer) { + int intValue = (Integer) value; + if (requiredType == Long.class) { + value = (long) intValue; + } else if (requiredType == Short.class && Short.MIN_VALUE <= intValue && intValue <= Short.MAX_VALUE) { + value = (short) intValue; + } else if (requiredType == Byte.class && Byte.MIN_VALUE <= intValue && intValue <= Byte.MAX_VALUE) { + value = (byte) intValue; } } - if (value instanceof Long && - (requiredType.equals(Integer.class) || requiredType.equals(Short.class) || requiredType.equals(Byte.class))) { - String msg = "Claim '" + name + "' value is too large or too small to be represented as a " + - requiredType.getName() + " instance (would cause numeric overflow)."; - throw new RequiredTypeException(msg); - } - if (!requiredType.isInstance(value)) { throw new RequiredTypeException(String.format(CONVERSION_ERROR_MSG, value.getClass(), requiredType)); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultClaimsBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultHeader.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultHeader.java (.../DefaultHeader.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultHeader.java (.../DefaultHeader.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,65 +16,57 @@ package io.jsonwebtoken.impl; import io.jsonwebtoken.Header; -import io.jsonwebtoken.impl.lang.CompactMediaTypeIdConverter; -import io.jsonwebtoken.impl.lang.Parameter; -import io.jsonwebtoken.impl.lang.Parameters; -import io.jsonwebtoken.lang.Registry; import io.jsonwebtoken.lang.Strings; import java.util.Map; -public class DefaultHeader extends ParameterMap implements Header { +@SuppressWarnings("unchecked") +public class DefaultHeader> extends JwtMap implements Header { - static final Parameter TYPE = Parameters.string(Header.TYPE, "Type"); - static final Parameter CONTENT_TYPE = Parameters.builder(String.class) - .setId(Header.CONTENT_TYPE).setName("Content Type") - .setConverter(CompactMediaTypeIdConverter.INSTANCE).build(); - static final Parameter ALGORITHM = Parameters.string(Header.ALGORITHM, "Algorithm"); - static final Parameter COMPRESSION_ALGORITHM = - Parameters.string(Header.COMPRESSION_ALGORITHM, "Compression Algorithm"); - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated // TODO: remove for 1.0.0: - static final Parameter DEPRECATED_COMPRESSION_ALGORITHM = - Parameters.string(Header.DEPRECATED_COMPRESSION_ALGORITHM, "Deprecated Compression Algorithm"); - - static final Registry> PARAMS = - Parameters.registry(TYPE, CONTENT_TYPE, ALGORITHM, COMPRESSION_ALGORITHM, DEPRECATED_COMPRESSION_ALGORITHM); - - public DefaultHeader(Map values) { - super(PARAMS, values); + public DefaultHeader() { + super(); } - protected DefaultHeader(Registry> registry, Map values) { - super(registry, values); + public DefaultHeader(Map map) { + super(map); } @Override - public String getName() { - return "JWT header"; + public String getType() { + return getString(TYPE); } @Override - public String getType() { - return get(TYPE); + public T setType(String typ) { + setValue(TYPE, typ); + return (T)this; } @Override public String getContentType() { - return get(CONTENT_TYPE); + return getString(CONTENT_TYPE); } @Override - public String getAlgorithm() { - return get(ALGORITHM); + public T setContentType(String cty) { + setValue(CONTENT_TYPE, cty); + return (T)this; } + @SuppressWarnings("deprecation") @Override public String getCompressionAlgorithm() { - String s = get(COMPRESSION_ALGORITHM); - if (!Strings.hasText(s)) { - s = get(DEPRECATED_COMPRESSION_ALGORITHM); + String alg = getString(COMPRESSION_ALGORITHM); + if (!Strings.hasText(alg)) { + alg = getString(DEPRECATED_COMPRESSION_ALGORITHM); } - return s; + return alg; } + + @Override + public T setCompressionAlgorithm(String compressionAlgorithm) { + setValue(COMPRESSION_ALGORITHM, compressionAlgorithm); + return (T) this; + } + } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwe.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJweHeader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJweHeaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJweHeaderMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJws.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJws.java (.../DefaultJws.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJws.java (.../DefaultJws.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,27 +17,36 @@ import io.jsonwebtoken.Jws; import io.jsonwebtoken.JwsHeader; -import io.jsonwebtoken.JwtVisitor; -import io.jsonwebtoken.io.Decoders; -public class DefaultJws

    extends DefaultProtectedJwt implements Jws

    { +public class DefaultJws implements Jws { - private static final String DIGEST_NAME = "signature"; - + private final JwsHeader header; + private final B body; private final String signature; - public DefaultJws(JwsHeader header, P payload, String signature) { - super(header, payload, Decoders.BASE64URL.decode(signature), DIGEST_NAME); + public DefaultJws(JwsHeader header, B body, String signature) { + this.header = header; + this.body = body; this.signature = signature; } @Override + public JwsHeader getHeader() { + return this.header; + } + + @Override + public B getBody() { + return this.body; + } + + @Override public String getSignature() { return this.signature; } @Override - public T accept(JwtVisitor v) { - return v.visit(this); + public String toString() { + return "header=" + header + ",body=" + body + ",signature=" + signature; } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwsHeader.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwsHeader.java (.../DefaultJwsHeader.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwsHeader.java (.../DefaultJwsHeader.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,35 +16,39 @@ package io.jsonwebtoken.impl; import io.jsonwebtoken.JwsHeader; -import io.jsonwebtoken.impl.lang.Parameter; -import io.jsonwebtoken.impl.lang.Parameters; -import io.jsonwebtoken.lang.Collections; -import io.jsonwebtoken.lang.Registry; import java.util.Map; -import java.util.Set; -public class DefaultJwsHeader extends DefaultProtectedHeader implements JwsHeader { +public class DefaultJwsHeader extends DefaultHeader implements JwsHeader { - // https://datatracker.ietf.org/doc/html/rfc7797#section-3 : - static final Parameter B64 = Parameters.builder(Boolean.class) - .setId("b64").setName("Base64url-Encode Payload").build(); + public DefaultJwsHeader() { + super(); + } - static final Registry> PARAMS = Parameters.registry(DefaultProtectedHeader.PARAMS, B64); + public DefaultJwsHeader(Map map) { + super(map); + } - public DefaultJwsHeader(Map map) { - super(PARAMS, map); + @Override + public String getAlgorithm() { + return getString(ALGORITHM); } @Override - public String getName() { - return "JWS header"; + public JwsHeader setAlgorithm(String alg) { + setValue(ALGORITHM, alg); + return this; } @Override - public boolean isPayloadEncoded() { - Set crit = Collections.nullSafe(getCritical()); - Boolean b64 = get(B64); - return b64 == null || b64 || !crit.contains(B64.getId()); + public String getKeyId() { + return getString(KEY_ID); } + + @Override + public JwsHeader setKeyId(String kid) { + setValue(KEY_ID, kid); + return this; + } + } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwt.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwt.java (.../DefaultJwt.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwt.java (.../DefaultJwt.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,73 +17,29 @@ import io.jsonwebtoken.Header; import io.jsonwebtoken.Jwt; -import io.jsonwebtoken.JwtVisitor; -import io.jsonwebtoken.io.Encoders; -import io.jsonwebtoken.lang.Assert; -import io.jsonwebtoken.lang.Objects; -public class DefaultJwt implements Jwt { +public class DefaultJwt implements Jwt { - private final H header; - private final P payload; + private final Header header; + private final B body; - public DefaultJwt(H header, P payload) { - this.header = Assert.notNull(header, "header cannot be null."); - this.payload = Assert.notNull(payload, "payload cannot be null."); + public DefaultJwt(Header header, B body) { + this.header = header; + this.body = body; } @Override - public H getHeader() { + public Header getHeader() { return header; } @Override - public P getBody() { - return getPayload(); + public B getBody() { + return body; } @Override - public P getPayload() { - return this.payload; + public String toString() { + return "header=" + header + ",body=" + body; } - - protected StringBuilder toStringBuilder() { - StringBuilder sb = new StringBuilder(100); - sb.append("header=").append(header).append(",payload="); - if (payload instanceof byte[]) { - String encoded = Encoders.BASE64URL.encode((byte[]) payload); - sb.append(encoded); - } else { - sb.append(payload); - } - return sb; - } - - @Override - public final String toString() { - return toStringBuilder().toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Jwt) { - Jwt jwt = (Jwt) obj; - return Objects.nullSafeEquals(header, jwt.getHeader()) && - Objects.nullSafeEquals(payload, jwt.getPayload()); - } - return false; - } - - @Override - public int hashCode() { - return Objects.nullSafeHashCode(header, payload); - } - - @Override - public T accept(JwtVisitor v) { - return v.visit(this); - } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtBuilder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtBuilder.java (.../DefaultJwtBuilder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtBuilder.java (.../DefaultJwtBuilder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,808 +16,378 @@ package io.jsonwebtoken.impl; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.CompressionCodec; import io.jsonwebtoken.Header; -import io.jsonwebtoken.JweHeader; import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.JwtBuilder; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.impl.io.Base64UrlStreamEncoder; -import io.jsonwebtoken.impl.io.ByteBase64UrlStreamEncoder; -import io.jsonwebtoken.impl.io.CountingInputStream; -import io.jsonwebtoken.impl.io.EncodingOutputStream; -import io.jsonwebtoken.impl.io.NamedSerializer; -import io.jsonwebtoken.impl.io.Streams; -import io.jsonwebtoken.impl.io.UncloseableInputStream; -import io.jsonwebtoken.impl.lang.Bytes; -import io.jsonwebtoken.impl.lang.Function; -import io.jsonwebtoken.impl.lang.Functions; -import io.jsonwebtoken.impl.lang.Parameter; -import io.jsonwebtoken.impl.lang.Services; -import io.jsonwebtoken.impl.security.DefaultAeadRequest; -import io.jsonwebtoken.impl.security.DefaultAeadResult; -import io.jsonwebtoken.impl.security.DefaultKeyRequest; -import io.jsonwebtoken.impl.security.DefaultSecureRequest; -import io.jsonwebtoken.impl.security.Pbes2HsAkwAlgorithm; -import io.jsonwebtoken.impl.security.ProviderKey; -import io.jsonwebtoken.impl.security.StandardSecureDigestAlgorithms; -import io.jsonwebtoken.io.CompressionAlgorithm; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.impl.crypto.DefaultJwtSigner; +import io.jsonwebtoken.impl.crypto.JwtSigner; +import io.jsonwebtoken.impl.lang.LegacyServices; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.Encoder; +import io.jsonwebtoken.io.Encoders; +import io.jsonwebtoken.io.SerializationException; 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; import io.jsonwebtoken.security.InvalidKeyException; -import io.jsonwebtoken.security.KeyAlgorithm; -import io.jsonwebtoken.security.KeyRequest; -import io.jsonwebtoken.security.KeyResult; -import io.jsonwebtoken.security.Password; -import io.jsonwebtoken.security.SecureDigestAlgorithm; -import io.jsonwebtoken.security.SecureRequest; -import io.jsonwebtoken.security.SecurityException; -import io.jsonwebtoken.security.SignatureException; -import io.jsonwebtoken.security.UnsupportedKeyException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.SequenceInputStream; import java.security.Key; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.PublicKey; -import java.security.SecureRandom; import java.util.Date; -import java.util.LinkedHashSet; import java.util.Map; -import java.util.Set; public class DefaultJwtBuilder implements JwtBuilder { - private static final String PUB_KEY_SIGN_MSG = "PublicKeys may not be used to create digital signatures. " + - "PrivateKeys are used to sign, and PublicKeys are used to verify."; + private Header header; + private Claims claims; + private String payload; - private static final String PRIV_KEY_ENC_MSG = "PrivateKeys may not be used to encrypt data. PublicKeys are " + - "used to encrypt, and PrivateKeys are used to decrypt."; - - protected Provider provider; - protected SecureRandom secureRandom; - - private final DefaultBuilderHeader headerBuilder; - private final DefaultBuilderClaims claimsBuilder; - - private Payload payload = Payload.EMPTY; - - private SecureDigestAlgorithm sigAlg = Jwts.SIG.NONE; - private Function, byte[]> signFunction; - - private AeadAlgorithm enc; // MUST be Symmetric AEAD per https://tools.ietf.org/html/rfc7516#section-4.1.2 - - private KeyAlgorithm keyAlg; - private Function, KeyResult> keyAlgFunction; - + private SignatureAlgorithm algorithm; private Key key; - private Serializer> serializer; + private Serializer> serializer; - protected Encoder encoder = Base64UrlStreamEncoder.INSTANCE; - private boolean encodePayload = true; - protected CompressionAlgorithm compressionAlgorithm; + private Encoder base64UrlEncoder = Encoders.BASE64URL; - public DefaultJwtBuilder() { - this.headerBuilder = new DefaultBuilderHeader(this); - this.claimsBuilder = new DefaultBuilderClaims(this); - } + private CompressionCodec compressionCodec; @Override - public BuilderHeader header() { - return this.headerBuilder; + public JwtBuilder serializeToJsonWith(Serializer> serializer) { + Assert.notNull(serializer, "Serializer cannot be null."); + this.serializer = serializer; + return this; } @Override - public BuilderClaims claims() { - return this.claimsBuilder; - } - - @Override - public JwtBuilder provider(Provider provider) { - this.provider = provider; + public JwtBuilder base64UrlEncodeWith(Encoder base64UrlEncoder) { + Assert.notNull(base64UrlEncoder, "base64UrlEncoder cannot be null."); + this.base64UrlEncoder = base64UrlEncoder; return this; } @Override - public JwtBuilder random(SecureRandom secureRandom) { - this.secureRandom = secureRandom; + public JwtBuilder setHeader(Header header) { + this.header = header; return this; } @Override - public JwtBuilder serializeToJsonWith(final Serializer> serializer) { - return json(serializer); - } - - @Override - public JwtBuilder json(Serializer> serializer) { - this.serializer = Assert.notNull(serializer, "JSON Serializer cannot be null."); + public JwtBuilder setHeader(Map header) { + this.header = new DefaultHeader(header); return this; } @Override - public JwtBuilder base64UrlEncodeWith(Encoder encoder) { - return b64Url(new ByteBase64UrlStreamEncoder(encoder)); - } + public JwtBuilder setHeaderParams(Map params) { + if (!Collections.isEmpty(params)) { - @Override - public JwtBuilder b64Url(Encoder encoder) { - Assert.notNull(encoder, "encoder cannot be null."); - this.encoder = encoder; + Header header = ensureHeader(); + + for (Map.Entry entry : params.entrySet()) { + header.put(entry.getKey(), entry.getValue()); + } + } return this; } - @Override - public JwtBuilder encodePayload(boolean b64) { - this.encodePayload = b64; - // clear out any previous values. They will be applied appropriately during compact() - String critParamId = DefaultProtectedHeader.CRIT.getId(); - String b64Id = DefaultJwsHeader.B64.getId(); - Set crit = this.headerBuilder.get(DefaultProtectedHeader.CRIT); - crit = new LinkedHashSet<>(Collections.nullSafe(crit)); - crit.remove(b64Id); - return header().delete(b64Id).add(critParamId, crit).and(); + protected Header ensureHeader() { + if (this.header == null) { + this.header = new DefaultHeader(); + } + return this.header; } @Override - public JwtBuilder setHeader(Map map) { - return header().empty().add(map).and(); - } - - @Override - public JwtBuilder setHeaderParams(Map params) { - return header().add(params).and(); - } - - @Override public JwtBuilder setHeaderParam(String name, Object value) { - return header().add(name, value).and(); + ensureHeader().put(name, value); + return this; } - protected static SecureDigestAlgorithm forSigningKey(K key) { - Assert.notNull(key, "Key cannot be null."); - SecureDigestAlgorithm alg = StandardSecureDigestAlgorithms.findBySigningKey(key); - if (alg == null) { - String msg = "Unable to determine a suitable MAC or Signature algorithm for the specified key using " + - "available heuristics: either the key size is too weak be used with available algorithms, or the " + - "key size is unavailable (e.g. if using a PKCS11 or HSM (Hardware Security Module) key store). " + - "If you are using a PKCS11 or HSM keystore, consider using the " + - "JwtBuilder.signWith(Key, SecureDigestAlgorithm) method instead."; - throw new UnsupportedKeyException(msg); - } - return alg; - } - @Override public JwtBuilder signWith(Key key) throws InvalidKeyException { Assert.notNull(key, "Key argument cannot be null."); - SecureDigestAlgorithm alg = forSigningKey(key); // https://github.com/jwtk/jjwt/issues/381 + SignatureAlgorithm alg = SignatureAlgorithm.forSigningKey(key); return signWith(key, alg); } @Override - public JwtBuilder signWith(K key, final SecureDigestAlgorithm alg) - throws InvalidKeyException { - + public JwtBuilder signWith(Key key, SignatureAlgorithm alg) throws InvalidKeyException { Assert.notNull(key, "Key argument cannot be null."); - if (key instanceof PublicKey) { // it's always wrong/insecure to try to create signatures with PublicKeys: - throw new IllegalArgumentException(PUB_KEY_SIGN_MSG); - } - // Implementation note: Ordinarily Passwords should not be used to create secure digests because they usually - // lack the length or entropy necessary for secure cryptographic operations, and are prone to misuse. - // However, we DO NOT prevent them as arguments here (like the above PublicKey check) because - // it is conceivable that a custom SecureDigestAlgorithm implementation would allow Password instances - // so that it might perform its own internal key-derivation logic producing a key that is then used to create a - // secure hash. - // - // Even so, a fallback safety check is that JJWT's only out-of-the-box Password implementation - // (io.jsonwebtoken.impl.security.PasswordSpec) explicitly forbids calls to password.getEncoded() in all - // scenarios to avoid potential misuse, so a digest algorithm implementation would explicitly need to avoid - // this by calling toCharArray() instead. - // - // TLDR; the digest algorithm implementation has the final say whether a password instance is valid - Assert.notNull(alg, "SignatureAlgorithm cannot be null."); - String id = Assert.hasText(alg.getId(), "SignatureAlgorithm id cannot be null or empty."); - if (Jwts.SIG.NONE.getId().equalsIgnoreCase(id)) { - String msg = "The 'none' JWS algorithm cannot be used to sign JWTs."; - throw new IllegalArgumentException(msg); - } + alg.assertValidSigningKey(key); //since 0.10.0 for https://github.com/jwtk/jjwt/issues/334 + this.algorithm = alg; this.key = key; - //noinspection unchecked - this.sigAlg = (SecureDigestAlgorithm) alg; - this.signFunction = Functions.wrap(new Function, byte[]>() { - @Override - public byte[] apply(SecureRequest request) { - return sigAlg.digest(request); - } - }, SignatureException.class, "Unable to compute %s signature.", id); return this; } - @SuppressWarnings({"deprecation", "unchecked"}) // TODO: remove method for 1.0 @Override - public JwtBuilder signWith(Key key, io.jsonwebtoken.SignatureAlgorithm alg) throws InvalidKeyException { + public JwtBuilder signWith(SignatureAlgorithm alg, byte[] secretKeyBytes) throws InvalidKeyException { Assert.notNull(alg, "SignatureAlgorithm cannot be null."); - alg.assertValidSigningKey(key); //since 0.10.0 for https://github.com/jwtk/jjwt/issues/334 - return signWith(key, (SecureDigestAlgorithm) Jwts.SIG.get().forKey(alg.getValue())); - } - - @SuppressWarnings("deprecation") // TODO: remove method for 1.0 - @Override - 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); } - @SuppressWarnings("deprecation") // TODO: remove method for 1.0 @Override - public JwtBuilder signWith(io.jsonwebtoken.SignatureAlgorithm alg, String base64EncodedSecretKey) throws InvalidKeyException { + public JwtBuilder signWith(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); } - @SuppressWarnings("deprecation") // TODO: remove method for 1.0 @Override - public JwtBuilder signWith(io.jsonwebtoken.SignatureAlgorithm alg, Key key) { + public JwtBuilder signWith(SignatureAlgorithm alg, Key key) { return signWith(key, alg); } @Override - public JwtBuilder encryptWith(SecretKey key, AeadAlgorithm enc) { - if (key instanceof Password) { - return encryptWith((Password) key, new Pbes2HsAkwAlgorithm(enc.getKeyBitLength()), enc); - } - return encryptWith(key, Jwts.KEY.DIRECT, enc); - } - - @Override - public JwtBuilder encryptWith(final K key, final KeyAlgorithm keyAlg, final AeadAlgorithm enc) { - this.enc = Assert.notNull(enc, "Encryption algorithm cannot be null."); - Assert.hasText(enc.getId(), "Encryption algorithm id cannot be null or empty."); - - Assert.notNull(key, "Encryption key cannot be null."); - if (key instanceof PrivateKey) { - throw new IllegalArgumentException(PRIV_KEY_ENC_MSG); - } - Assert.notNull(keyAlg, "KeyAlgorithm cannot be null."); - final String algId = Assert.hasText(keyAlg.getId(), "KeyAlgorithm id cannot be null or empty."); - - this.key = key; - //noinspection unchecked - this.keyAlg = (KeyAlgorithm) keyAlg; - final KeyAlgorithm alg = this.keyAlg; - - final String cekMsg = "Unable to obtain content encryption key from key management algorithm '%s'."; - this.keyAlgFunction = Functions.wrap(new Function, KeyResult>() { - @Override - public KeyResult apply(KeyRequest request) { - return alg.getEncryptionKey(request); - } - }, SecurityException.class, cekMsg, algId); - + public JwtBuilder compressWith(CompressionCodec compressionCodec) { + Assert.notNull(compressionCodec, "compressionCodec cannot be null"); + this.compressionCodec = compressionCodec; return this; } @Override - public JwtBuilder compressWith(CompressionAlgorithm alg) { - Assert.notNull(alg, "CompressionAlgorithm cannot be null"); - Assert.hasText(alg.getId(), "CompressionAlgorithm id cannot be null or empty."); - this.compressionAlgorithm = alg; - // clear out any previous value that might have been there. It'll be added back to match this - // specific algorithm in the compact() method implementation - return header().delete(DefaultHeader.COMPRESSION_ALGORITHM.getId()).and(); - } - - @Override public JwtBuilder setPayload(String payload) { - return content(payload); - } - - @Override - public JwtBuilder content(String content) { - if (Strings.hasText(content)) { - this.payload = new Payload(content, null); - } + this.payload = payload; return this; } - @Override - public JwtBuilder content(byte[] content) { - if (!Bytes.isEmpty(content)) { - this.payload = new Payload(content, null); + protected Claims ensureClaims() { + if (this.claims == null) { + this.claims = new DefaultClaims(); } - return this; + return this.claims; } @Override - public JwtBuilder content(InputStream in) { - if (in != null) { - this.payload = new Payload(in, null); - } + public JwtBuilder setClaims(Claims claims) { + this.claims = claims; return this; } @Override - 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."); - this.payload = new Payload(content, cty); - // clear out any previous value - it will be set appropriately during compact() - return header().delete(DefaultHeader.CONTENT_TYPE.getId()).and(); - } - - @Override - public JwtBuilder content(String content, String cty) throws IllegalArgumentException { - Assert.hasText(content, "Content string cannot be null or empty."); - Assert.hasText(cty, "ContentType string cannot be null or empty."); - this.payload = new Payload(content, cty); - // clear out any previous value - it will be set appropriately during compact() - return header().delete(DefaultHeader.CONTENT_TYPE.getId()).and(); - } - - @Override - public JwtBuilder content(InputStream in, String cty) throws IllegalArgumentException { - Assert.notNull(in, "Payload InputStream cannot be null."); - Assert.hasText(cty, "ContentType string cannot be null or empty."); - this.payload = new Payload(in, cty); - // clear out any previous value - it will be set appropriately during compact() - return header().delete(DefaultHeader.CONTENT_TYPE.getId()).and(); - } - - @Override public JwtBuilder setClaims(Map claims) { - Assert.notNull(claims, "Claims map cannot be null."); - return claims().empty().add(claims).and(); + this.claims = new DefaultClaims(claims); + return this; } @Override - public JwtBuilder addClaims(Map claims) { - return claims(claims); + public JwtBuilder addClaims(Map claims) { + ensureClaims().putAll(claims); + return this; } @Override - public JwtBuilder claims(Map 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) { - return issuer(iss); + if (Strings.hasText(iss)) { + ensureClaims().setIssuer(iss); + } else { + if (this.claims != null) { + claims.setIssuer(iss); + } + } + return this; } @Override - public JwtBuilder issuer(String iss) { - return claims().issuer(iss).and(); - } - - @Override public JwtBuilder setSubject(String sub) { - return subject(sub); + if (Strings.hasText(sub)) { + ensureClaims().setSubject(sub); + } else { + if (this.claims != null) { + claims.setSubject(sub); + } + } + return this; } @Override - public JwtBuilder subject(String sub) { - return claims().subject(sub).and(); - } - - @Override public JwtBuilder setAudience(String aud) { - //noinspection deprecation - return claims().setAudience(aud).and(); + if (Strings.hasText(aud)) { + ensureClaims().setAudience(aud); + } else { + if (this.claims != null) { + claims.setAudience(aud); + } + } + return this; } @Override - public AudienceCollection audience() { - return new DelegateAudienceCollection<>((JwtBuilder) this, claims().audience()); - } - - @Override public JwtBuilder setExpiration(Date exp) { - return expiration(exp); + if (exp != null) { + ensureClaims().setExpiration(exp); + } else { + if (this.claims != null) { + //noinspection ConstantConditions + this.claims.setExpiration(exp); + } + } + return this; } @Override - public JwtBuilder expiration(Date exp) { - return claims().expiration(exp).and(); - } - - @Override public JwtBuilder setNotBefore(Date nbf) { - return notBefore(nbf); + if (nbf != null) { + ensureClaims().setNotBefore(nbf); + } else { + if (this.claims != null) { + //noinspection ConstantConditions + this.claims.setNotBefore(nbf); + } + } + return this; } @Override - public JwtBuilder notBefore(Date nbf) { - return claims().notBefore(nbf).and(); - } - - @Override public JwtBuilder setIssuedAt(Date iat) { - return issuedAt(iat); + if (iat != null) { + ensureClaims().setIssuedAt(iat); + } else { + if (this.claims != null) { + //noinspection ConstantConditions + this.claims.setIssuedAt(iat); + } + } + return this; } @Override - public JwtBuilder issuedAt(Date iat) { - return claims().issuedAt(iat).and(); - } - - @Override public JwtBuilder setId(String jti) { - return id(jti); + if (Strings.hasText(jti)) { + ensureClaims().setId(jti); + } else { + if (this.claims != null) { + claims.setId(jti); + } + } + return this; } @Override - public JwtBuilder id(String jti) { - return claims().id(jti).and(); - } - - private void assertPayloadEncoding(String type) { - if (!this.encodePayload) { - String msg = "Payload encoding may not be disabled for " + type + "s, only JWSs."; - throw new IllegalArgumentException(msg); + public JwtBuilder claim(String name, Object value) { + Assert.hasText(name, "Claim property name cannot be null or empty."); + if (this.claims == null) { + if (value != null) { + ensureClaims().put(name, value); + } + } else { + if (value == null) { + this.claims.remove(name); + } else { + this.claims.put(name, value); + } } + + return this; } @Override public String compact() { - final boolean jwe = this.enc != null; - - if (jwe && signFunction != null) { - String msg = "Both 'signWith' and 'encryptWith' cannot be specified. Choose either one."; - throw new IllegalStateException(msg); + if (this.serializer == null) { + // try to find one based on the services available + // TODO: This util class will throw a UnavailableImplementationException here to retain behavior of previous version, remove in v1.0 + // use the previous commented out line instead + this.serializer = LegacyServices.loadFirst(Serializer.class); } - Payload payload = Assert.stateNotNull(this.payload, "Payload instance null, internal error"); - final Claims claims = this.claimsBuilder.build(); - - if (jwe && payload.isEmpty() && Collections.isEmpty(claims)) { // JWE payload can never be empty: - String msg = "Encrypted JWTs must have either 'claims' or non-empty 'content'."; - throw new IllegalStateException(msg); - } // otherwise JWS and Unprotected JWT payloads can be empty - - if (!payload.isEmpty() && !Collections.isEmpty(claims)) { - throw new IllegalStateException("Both 'content' and 'claims' cannot be specified. Choose either one."); + if (payload == null && Collections.isEmpty(claims)) { + payload = ""; } - if (this.serializer == null) { // try to find one based on the services available - //noinspection unchecked - json(Services.get(Serializer.class)); + if (payload != null && !Collections.isEmpty(claims)) { + throw new IllegalStateException("Both 'payload' and 'claims' cannot both be specified. Choose either one."); } - if (!Collections.isEmpty(claims)) { // normalize so we have one object to deal with: - payload = new Payload(claims); - } - if (compressionAlgorithm != null && !payload.isEmpty()) { - payload.setZip(compressionAlgorithm); - this.headerBuilder.put(DefaultHeader.COMPRESSION_ALGORITHM.getId(), compressionAlgorithm.getId()); - } + Header header = ensureHeader(); - if (Strings.hasText(payload.getContentType())) { - // We retain the value from the content* calls to prevent accidental removal from - // header().empty() or header().delete calls - this.headerBuilder.contentType(payload.getContentType()); - } - - Provider keyProvider = ProviderKey.getProvider(this.key, this.provider); - Key key = ProviderKey.getKey(this.key); - if (jwe) { - return encrypt(payload, key, keyProvider); - } else if (key != null) { - return sign(payload, key, keyProvider); + JwsHeader jwsHeader; + if (header instanceof JwsHeader) { + jwsHeader = (JwsHeader) header; } else { - return unprotected(payload); + //noinspection unchecked + jwsHeader = new DefaultJwsHeader(header); } - } - // automatically closes the OutputStream - private void writeAndClose(String name, Map map, OutputStream out) { - try { - Serializer> named = new NamedSerializer(name, this.serializer); - named.serialize(map, out); - } finally { - Objects.nullSafeClose(out); - } - } - - private void writeAndClose(String name, final Payload payload, OutputStream out) { - out = payload.compress(out); // compression if necessary - if (payload.isClaims()) { - writeAndClose(name, payload.getRequiredClaims(), out); + if (key != null) { + jwsHeader.setAlgorithm(algorithm.getValue()); } else { - try { - InputStream in = payload.toInputStream(); - Streams.copy(in, out, new byte[4096], "Unable to copy payload."); - } finally { - Objects.nullSafeClose(out); - } + //no signature - plaintext JWT: + jwsHeader.setAlgorithm(SignatureAlgorithm.NONE.getValue()); } - } - private String sign(final Payload payload, final Key key, final Provider provider) { - - Assert.stateNotNull(key, "Key is required."); // set by signWithWith* - Assert.stateNotNull(sigAlg, "SignatureAlgorithm is required."); // invariant - Assert.stateNotNull(signFunction, "Signature Algorithm function cannot be null."); - Assert.stateNotNull(payload, "Payload argument cannot be null."); - - final ByteArrayOutputStream jws = new ByteArrayOutputStream(4096); - - // ----- header ----- - this.headerBuilder.add(DefaultHeader.ALGORITHM.getId(), sigAlg.getId()); - if (!this.encodePayload) { // b64 extension: - String id = DefaultJwsHeader.B64.getId(); - this.headerBuilder.critical().add(id).and().add(id, false); + if (compressionCodec != null) { + jwsHeader.setCompressionAlgorithm(compressionCodec.getAlgorithmName()); } - final JwsHeader header = Assert.isInstanceOf(JwsHeader.class, this.headerBuilder.build()); - encodeAndWrite("JWS Protected Header", header, jws); - // ----- separator ----- - jws.write(DefaultJwtParser.SEPARATOR_CHAR); + String base64UrlEncodedHeader = base64UrlEncode(jwsHeader, "Unable to serialize header to json."); - // ----- payload ----- - // Logic defined by table in https://datatracker.ietf.org/doc/html/rfc7797#section-3 : - InputStream signingInput; - InputStream payloadStream = null; // not needed unless b64 is enabled - if (this.encodePayload) { - encodeAndWrite("JWS Payload", payload, jws); - signingInput = Streams.of(jws.toByteArray()); - } else { // b64 - - // First, ensure we have the base64url header bytes + the SEPARATOR_CHAR byte: - InputStream prefixStream = Streams.of(jws.toByteArray()); - - // Next, b64 extension requires the raw (non-encoded) payload to be included directly in the signing input, - // so we ensure we have an input stream for that: - if (payload.isClaims() || payload.isCompressed()) { - ByteArrayOutputStream claimsOut = new ByteArrayOutputStream(8192); - writeAndClose("JWS Unencoded Payload", payload, claimsOut); - payloadStream = Streams.of(claimsOut.toByteArray()); - } else { - // No claims and not compressed, so just get the direct InputStream: - payloadStream = Assert.stateNotNull(payload.toInputStream(), "Payload InputStream cannot be null."); - } - if (!payload.isClaims()) { - payloadStream = new CountingInputStream(payloadStream); // we'll need to assert if it's empty later - } - if (payloadStream.markSupported()) { - payloadStream.mark(0); // to rewind - } - - // (base64url header bytes + separator char) + raw payload bytes: - // and don't let the SequenceInputStream close the payloadStream in case reset is needed: - signingInput = new SequenceInputStream(prefixStream, new UncloseableInputStream(payloadStream)); + byte[] bytes; + try { + bytes = this.payload != null ? payload.getBytes(Strings.UTF_8) : toJson(claims); + } catch (SerializationException e) { + throw new IllegalArgumentException("Unable to serialize claims object to json: " + e.getMessage(), e); } - byte[] signature; - try { - SecureRequest request = new DefaultSecureRequest<>(signingInput, provider, secureRandom, key); - signature = signFunction.apply(request); - - // now that we've calculated the signature, if using the b64 extension, and the payload is - // attached ('non-detached'), we need to include it in the jws before the signature token. - // (Note that if encodePayload is true, the payload has already been written to jws at this point, so - // we only need to write if encodePayload is false and the payload is attached): - if (!this.encodePayload) { - if (!payload.isCompressed() // don't print raw compressed bytes - && (payload.isClaims() || payload.isString())) { - // now add the payload to the jws output: - Streams.copy(payloadStream, jws, new byte[8192], "Unable to copy attached Payload InputStream."); - } - if (payloadStream instanceof CountingInputStream && ((CountingInputStream) payloadStream).getCount() <= 0) { - String msg = "'b64' Unencoded payload option has been specified, but payload is empty."; - throw new IllegalStateException(msg); - } - } - } finally { - Streams.reset(payloadStream); + if (compressionCodec != null) { + bytes = compressionCodec.compress(bytes); } - // ----- separator ----- - jws.write(DefaultJwtParser.SEPARATOR_CHAR); + String base64UrlEncodedBody = base64UrlEncoder.encode(bytes); - // ----- signature ----- - encodeAndWrite("JWS Signature", signature, jws); + String jwt = base64UrlEncodedHeader + JwtParser.SEPARATOR_CHAR + base64UrlEncodedBody; - return Strings.utf8(jws.toByteArray()); - } + if (key != null) { //jwt must be signed: - private String unprotected(final Payload content) { + JwtSigner signer = createSigner(algorithm, key); - Assert.stateNotNull(content, "Content argument cannot be null."); - assertPayloadEncoding("unprotected JWT"); + String base64UrlSignature = signer.sign(jwt); - this.headerBuilder.add(DefaultHeader.ALGORITHM.getId(), Jwts.SIG.NONE.getId()); - - final ByteArrayOutputStream jwt = new ByteArrayOutputStream(512); - - // ----- header ----- - final Header header = this.headerBuilder.build(); - encodeAndWrite("JWT Header", header, jwt); - - // ----- separator ----- - jwt.write(DefaultJwtParser.SEPARATOR_CHAR); - - // ----- payload ----- - encodeAndWrite("JWT Payload", content, jwt); - - // ----- period terminator ----- - jwt.write(DefaultJwtParser.SEPARATOR_CHAR); // https://www.rfc-editor.org/rfc/rfc7519#section-6.1 - - return Strings.ascii(jwt.toByteArray()); - } - - private void encrypt(final AeadRequest req, final AeadResult res) throws SecurityException { - Function fn = Functions.wrap(new Function() { - @Override - public Object apply(Object o) { - enc.encrypt(req, res); - return null; - } - }, SecurityException.class, "%s encryption failed.", enc.getId()); - fn.apply(null); - } - - private String encrypt(final Payload content, final Key key, final Provider keyProvider) { - - Assert.stateNotNull(content, "Payload argument cannot be null."); - Assert.stateNotNull(key, "Key is required."); // set by encryptWith* - Assert.stateNotNull(enc, "Encryption algorithm is required."); // set by encryptWith* - Assert.stateNotNull(keyAlg, "KeyAlgorithm is required."); //set by encryptWith* - Assert.stateNotNull(keyAlgFunction, "KeyAlgorithm function cannot be null."); - assertPayloadEncoding("JWE"); - - InputStream plaintext; - if (content.isClaims()) { - ByteArrayOutputStream out = new ByteArrayOutputStream(4096); - writeAndClose("JWE Claims", content, out); - plaintext = Streams.of(out.toByteArray()); + jwt += JwtParser.SEPARATOR_CHAR + base64UrlSignature; } else { - plaintext = content.toInputStream(); + // no signature (plaintext), but must terminate w/ a period, see + // https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-6.1 + jwt += JwtParser.SEPARATOR_CHAR; } - //only expose (mutable) JweHeader functionality to KeyAlgorithm instances, not the full headerBuilder - // (which exposes this JwtBuilder and shouldn't be referenced by KeyAlgorithms): - JweHeader delegate = new DefaultMutableJweHeader(this.headerBuilder); - KeyRequest keyRequest = new DefaultKeyRequest<>(key, keyProvider, this.secureRandom, delegate, enc); - KeyResult keyResult = keyAlgFunction.apply(keyRequest); - Assert.stateNotNull(keyResult, "KeyAlgorithm must return a KeyResult."); - - 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.add(DefaultHeader.ALGORITHM.getId(), keyAlg.getId()); - this.headerBuilder.put(DefaultJweHeader.ENCRYPTION_ALGORITHM.getId(), enc.getId()); - - final JweHeader header = Assert.isInstanceOf(JweHeader.class, this.headerBuilder.build(), - "Invalid header created: "); - - // ----- header ----- - ByteArrayOutputStream jwe = new ByteArrayOutputStream(8192); - encodeAndWrite("JWE Protected Header", header, jwe); - - // JWE RFC requires AAD to be the ASCII bytes of the Base64URL-encoded header. Since the header bytes are - // already Base64URL-encoded at this point (via the encoder.wrap call just above), and Base64Url-encoding uses - // only ASCII characters, we don't need to use StandardCharsets.US_ASCII to explicitly convert here - just - // use the already-encoded (ascii) bytes: - InputStream aad = Streams.of(jwe.toByteArray()); - - // During encryption, the configured Provider applies to the KeyAlgorithm, not the AeadAlgorithm, mostly - // because all JVMs support the standard AeadAlgorithms (especially with BouncyCastle in the classpath). - // As such, the provider here is intentionally omitted (null): - // TODO: add encProvider(Provider) builder method that applies to this request only? - ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(8192); - AeadRequest req = new DefaultAeadRequest(plaintext, null, secureRandom, cek, aad); - DefaultAeadResult res = new DefaultAeadResult(ciphertextOut); - encrypt(req, res); - - byte[] iv = Assert.notEmpty(res.getIv(), "Encryption result must have a non-empty initialization vector."); - byte[] tag = Assert.notEmpty(res.getDigest(), "Encryption result must have a non-empty authentication tag."); - byte[] ciphertext = Assert.notEmpty(ciphertextOut.toByteArray(), "Encryption result must have non-empty ciphertext."); - - jwe.write(DefaultJwtParser.SEPARATOR_CHAR); - encodeAndWrite("JWE Encrypted CEK", encryptedCek, jwe); - - jwe.write(DefaultJwtParser.SEPARATOR_CHAR); - encodeAndWrite("JWE Initialization Vector", iv, jwe); - - jwe.write(DefaultJwtParser.SEPARATOR_CHAR); - encodeAndWrite("JWE Ciphertext", ciphertext, jwe); - - jwe.write(DefaultJwtParser.SEPARATOR_CHAR); - encodeAndWrite("JWE AAD Tag", tag, jwe); - - return Strings.utf8(jwe.toByteArray()); + return jwt; } - private static class DefaultBuilderClaims extends DelegatingClaimsMutator implements BuilderClaims { - - private final 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); - } + /* + * @since 0.5 mostly to allow testing overrides + */ + protected JwtSigner createSigner(SignatureAlgorithm alg, Key key) { + return new DefaultJwtSigner(alg, key, base64UrlEncoder); } - private static class DefaultBuilderHeader extends DefaultJweHeaderBuilder implements BuilderHeader { - - private final JwtBuilder builder; - - private DefaultBuilderHeader(JwtBuilder builder) { - super(); - this.builder = Assert.notNull(builder, "JwtBuilder cannot be null."); + @Deprecated // remove before 1.0 - call the serializer and base64UrlEncoder directly + protected String base64UrlEncode(Object o, String errMsg) { + Assert.isInstanceOf(Map.class, o, "object argument must be a map."); + Map m = (Map)o; + byte[] bytes; + try { + bytes = toJson(m); + } catch (SerializationException e) { + throw new IllegalStateException(errMsg, e); } - @Override - public JwtBuilder and() { - return builder; - } - - @SuppressWarnings("SameParameterValue") - private T get(Parameter param) { - return this.DELEGATE.get(param); - } - - private Header build() { - return new DefaultJwtHeaderBuilder(this).build(); - } + return base64UrlEncoder.encode(bytes); } - private OutputStream encode(OutputStream out, String name) { - out = this.encoder.encode(out); - return new EncodingOutputStream(out, "base64url", name); + @SuppressWarnings("unchecked") + @Deprecated //remove before 1.0 - call the serializer directly + protected byte[] toJson(Object object) throws SerializationException { + Assert.isInstanceOf(Map.class, object, "object argument must be a map."); + Map m = (Map)object; + return serializer.serialize(m); } - - private void encodeAndWrite(String name, Map map, OutputStream out) { - out = encode(out, name); - writeAndClose(name, map, out); - } - - private void encodeAndWrite(String name, Payload payload, OutputStream out) { - out = encode(out, name); - writeAndClose(name, payload, out); - } - - private void encodeAndWrite(String name, byte[] data, OutputStream out) { - out = encode(out, name); - Streams.writeAndClose(out, data, "Unable to write bytes"); - } - } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtHeaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtParser.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtParser.java (.../DefaultJwtParser.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtParser.java (.../DefaultJwtParser.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,646 +15,412 @@ */ package io.jsonwebtoken.impl; +import io.jsonwebtoken.ClaimJwtException; import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ClaimsBuilder; import io.jsonwebtoken.Clock; +import io.jsonwebtoken.CompressionCodec; import io.jsonwebtoken.CompressionCodecResolver; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Header; import io.jsonwebtoken.IncorrectClaimException; -import io.jsonwebtoken.Jwe; -import io.jsonwebtoken.JweHeader; +import io.jsonwebtoken.InvalidClaimException; import io.jsonwebtoken.Jws; import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.Jwt; -import io.jsonwebtoken.JwtException; import io.jsonwebtoken.JwtHandler; +import io.jsonwebtoken.JwtHandlerAdapter; import io.jsonwebtoken.JwtParser; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.Locator; import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.MissingClaimException; import io.jsonwebtoken.PrematureJwtException; -import io.jsonwebtoken.ProtectedHeader; +import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SigningKeyResolver; import io.jsonwebtoken.UnsupportedJwtException; -import io.jsonwebtoken.impl.io.AbstractParser; -import io.jsonwebtoken.impl.io.BytesInputStream; -import io.jsonwebtoken.impl.io.CharSequenceReader; -import io.jsonwebtoken.impl.io.JsonObjectDeserializer; -import io.jsonwebtoken.impl.io.Streams; -import io.jsonwebtoken.impl.io.UncloseableInputStream; -import io.jsonwebtoken.impl.lang.Bytes; -import io.jsonwebtoken.impl.lang.Function; -import io.jsonwebtoken.impl.lang.RedactedSupplier; -import io.jsonwebtoken.impl.security.DefaultDecryptAeadRequest; -import io.jsonwebtoken.impl.security.DefaultDecryptionKeyRequest; -import io.jsonwebtoken.impl.security.DefaultVerifySecureDigestRequest; -import io.jsonwebtoken.impl.security.LocatingKeyResolver; -import io.jsonwebtoken.impl.security.ProviderKey; -import io.jsonwebtoken.io.CompressionAlgorithm; +import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver; +import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator; +import io.jsonwebtoken.impl.crypto.JwtSignatureValidator; +import io.jsonwebtoken.impl.lang.LegacyServices; import io.jsonwebtoken.io.Decoder; +import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.DeserializationException; import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.lang.Assert; -import io.jsonwebtoken.lang.Collections; import io.jsonwebtoken.lang.DateFormats; import io.jsonwebtoken.lang.Objects; -import io.jsonwebtoken.lang.Registry; import io.jsonwebtoken.lang.Strings; -import io.jsonwebtoken.security.AeadAlgorithm; -import io.jsonwebtoken.security.DecryptAeadRequest; -import io.jsonwebtoken.security.DecryptionKeyRequest; import io.jsonwebtoken.security.InvalidKeyException; -import io.jsonwebtoken.security.KeyAlgorithm; -import io.jsonwebtoken.security.SecureDigestAlgorithm; import io.jsonwebtoken.security.SignatureException; -import io.jsonwebtoken.security.VerifySecureDigestRequest; import io.jsonwebtoken.security.WeakKeyException; -import javax.crypto.SecretKey; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.Reader; -import java.io.SequenceInputStream; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; +import javax.crypto.spec.SecretKeySpec; 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; import java.util.Map; -import java.util.Set; @SuppressWarnings("unchecked") -public class DefaultJwtParser extends AbstractParser> implements JwtParser { +public class DefaultJwtParser implements JwtParser { - static final char SEPARATOR_CHAR = '.'; + private static final int MILLISECONDS_PER_SECOND = 1000; - private static final JwtTokenizer jwtTokenizer = new JwtTokenizer(); + // TODO: make the folling fields final for v1.0 + private byte[] keyBytes; - static final String PRIV_KEY_VERIFY_MSG = "PrivateKeys may not be used to verify digital signatures. " + - "PrivateKeys are used to sign, and PublicKeys are used to verify."; + private Key key; - static final String PUB_KEY_DECRYPT_MSG = "PublicKeys may not be used to decrypt data. PublicKeys are " + - "used to encrypt, and PrivateKeys are used to decrypt."; + private SigningKeyResolver signingKeyResolver; - public static final String INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE = "Expected %s claim to be: %s, but was: %s."; + private CompressionCodecResolver compressionCodecResolver = new DefaultCompressionCodecResolver(); - public static final String MISSING_EXPECTED_CLAIM_VALUE_MESSAGE_TEMPLATE = - "Missing expected '%s' value in '%s' claim %s."; + private Decoder base64UrlDecoder = Decoders.BASE64URL; - public static final String MISSING_JWS_ALG_MSG = "JWS header does not contain a required 'alg' (Algorithm) " + - "header parameter. This header parameter is mandatory per the JWS Specification, Section 4.1.1. See " + - "https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.1 for more information."; + private Deserializer> deserializer; - public static final String MISSING_JWE_ALG_MSG = "JWE header does not contain a required 'alg' (Algorithm) " + - "header parameter. This header parameter is mandatory per the JWE Specification, Section 4.1.1. See " + - "https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.1 for more information."; + private Claims expectedClaims = new DefaultClaims(); - public static final String MISSING_JWS_DIGEST_MSG_FMT = "The JWS header references signature algorithm '%s' but " + - "the compact JWE string is missing the required signature."; + private Clock clock = DefaultClock.INSTANCE; - 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."; + private long allowedClockSkewMillis = 0; - 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."; + /** + * TODO: remove this constructor before 1.0 + * @deprecated for backward compatibility only, see other constructors. + */ + @Deprecated + public DefaultJwtParser() { } - 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.unsecured() method, but please read the " + - "security considerations covered in that method's JavaDoc before doing so. Header: "; + DefaultJwtParser(SigningKeyResolver signingKeyResolver, + Key key, + byte[] keyBytes, + Clock clock, + long allowedClockSkewMillis, + Claims expectedClaims, + Decoder base64UrlDecoder, + Deserializer> deserializer, + CompressionCodecResolver compressionCodecResolver) { + this.signingKeyResolver = signingKeyResolver; + this.key = key; + this.keyBytes = keyBytes; + this.clock = clock; + this.allowedClockSkewMillis = allowedClockSkewMillis; + this.expectedClaims = expectedClaims; + this.base64UrlDecoder = base64UrlDecoder; + this.deserializer = deserializer; + this.compressionCodecResolver = compressionCodecResolver; + } - private static final String CRIT_UNSECURED_MSG = "Unsecured JWSs (those with an " + DefaultHeader.ALGORITHM + - " header value of '" + Jwts.SIG.NONE.getId() + "') may not use the " + DefaultProtectedHeader.CRIT + - " header parameter per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11 (\"the [crit] Header " + - "Parameter MUST be integrity protected; therefore, it MUST occur only within [a] JWS Protected Header)\"." + - " Header: %s"; + @Override + public JwtParser deserializeJsonWith(Deserializer> deserializer) { + Assert.notNull(deserializer, "deserializer cannot be null."); + this.deserializer = deserializer; + return this; + } - private static final String CRIT_MISSING_MSG = "Protected Header " + - DefaultProtectedHeader.CRIT + " set references header name '%s', but the header does not contain an " + - "associated '%s' header parameter as required by " + - "https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11. Header: %s"; + @Override + public JwtParser base64UrlDecodeWith(Decoder base64UrlDecoder) { + Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null."); + this.base64UrlDecoder = base64UrlDecoder; + return this; + } - private static final String CRIT_UNSUPPORTED_MSG = "Protected Header " + DefaultProtectedHeader.CRIT + - " set references unsupported header name '%s'. Application developers expecting to support a JWT " + - "extension using header '%s' in their application code must indicate it " + - "is supported by using the JwtParserBuilder.critical method. Header: %s"; + @Override + public JwtParser requireIssuedAt(Date issuedAt) { + expectedClaims.setIssuedAt(issuedAt); + return this; + } - private static final String JWE_NONE_MSG = "JWEs do not support key management " + DefaultHeader.ALGORITHM + - " header value '" + Jwts.SIG.NONE.getId() + "' per " + - "https://www.rfc-editor.org/rfc/rfc7518.html#section-4.1"; + @Override + public JwtParser requireIssuer(String issuer) { + expectedClaims.setIssuer(issuer); + return this; + } - private static final String JWS_NONE_SIG_MISMATCH_MSG = "The JWS header references signature algorithm '" + - Jwts.SIG.NONE.getId() + "' yet the compact JWS string contains a signature. This is not permitted " + - "per https://tools.ietf.org/html/rfc7518#section-3.6."; + @Override + public JwtParser requireAudience(String audience) { + expectedClaims.setAudience(audience); + return this; + } - private static final String B64_MISSING_PAYLOAD = "Unable to verify JWS signature: the parser has encountered an " + - "Unencoded Payload JWS with detached payload, but the detached payload value required for signature " + - "verification has not been provided. If you expect to receive and parse Unencoded Payload JWSs in your " + - "application, the overloaded JwtParser.parseSignedContent or JwtParser.parseSignedClaims methods that " + - "accept a byte[] or InputStream must be used for these kinds of JWSs. Header: %s"; + @Override + public JwtParser requireSubject(String subject) { + expectedClaims.setSubject(subject); + return this; + } - private static final String B64_DECOMPRESSION_MSG = "The JWT header references compression algorithm " + - "'%s', but payload decompression for Unencoded JWSs (those with an " + DefaultJwsHeader.B64 + - " header value of false) that rely on a SigningKeyResolver are disallowed " + - "by default to protect against [Denial of Service attacks](" + - "https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf). If you " + - "wish to enable Unencoded JWS payload decompression, configure the JwtParserBuilder." + - "keyLocator(Locator) and do not configure a SigningKeyResolver."; + @Override + public JwtParser requireId(String id) { + expectedClaims.setId(id); + return this; + } - private static final String UNPROTECTED_DECOMPRESSION_MSG = "The JWT header references compression algorithm " + - "'%s', but payload decompression for Unprotected JWTs (those with an " + DefaultHeader.ALGORITHM + - " header value of '" + Jwts.SIG.NONE.getId() + "') or Unencoded JWSs (those with a " + - DefaultJwsHeader.B64 + " header value of false) that also rely on a SigningKeyResolver are disallowed " + - "by default to protect against [Denial of Service attacks](" + - "https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf). If you " + - "wish to enable Unsecure JWS or Unencoded JWS payload decompression, call the JwtParserBuilder." + - "unsecuredDecompression() method, but please read the security considerations covered in that " + - "method's JavaDoc before doing so."; + @Override + public JwtParser requireExpiration(Date expiration) { + expectedClaims.setExpiration(expiration); + return this; + } - private final Provider provider; + @Override + public JwtParser requireNotBefore(Date notBefore) { + expectedClaims.setNotBefore(notBefore); + return this; + } - @SuppressWarnings("deprecation") - private final SigningKeyResolver signingKeyResolver; + @Override + public JwtParser 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.put(claimName, value); + return this; + } - private final boolean unsecured; + @Override + public JwtParser setClock(Clock clock) { + Assert.notNull(clock, "Clock instance cannot be null."); + this.clock = clock; + return this; + } - private final boolean unsecuredDecompression; + @Override + public JwtParser setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException { + Assert.isTrue(seconds <= DefaultJwtParserBuilder.MAX_CLOCK_SKEW_MILLIS, DefaultJwtParserBuilder.MAX_CLOCK_SKEW_ILLEGAL_MSG); + this.allowedClockSkewMillis = Math.max(0, seconds * MILLISECONDS_PER_SECOND); + return this; + } - private final Function> sigAlgs; + @Override + public JwtParser setSigningKey(byte[] key) { + Assert.notEmpty(key, "signing key cannot be null or empty."); + this.keyBytes = key; + return this; + } - private final Function encAlgs; + @Override + public JwtParser setSigningKey(String base64EncodedSecretKey) { + Assert.hasText(base64EncodedSecretKey, "signing key cannot be null or empty."); + this.keyBytes = Decoders.BASE64.decode(base64EncodedSecretKey); + return this; + } - private final Function> keyAlgs; + @Override + public JwtParser setSigningKey(Key key) { + Assert.notNull(key, "signing key cannot be null."); + this.key = key; + return this; + } - private final Function zipAlgs; + @Override + public JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver) { + Assert.notNull(signingKeyResolver, "SigningKeyResolver cannot be null."); + this.signingKeyResolver = signingKeyResolver; + return this; + } - private final Locator keyLocator; + @Override + public JwtParser setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver) { + Assert.notNull(compressionCodecResolver, "compressionCodecResolver cannot be null."); + this.compressionCodecResolver = compressionCodecResolver; + return this; + } - private final Decoder decoder; + @Override + public boolean isSigned(String jwt) { - private final Deserializer> deserializer; + if (jwt == null) { + return false; + } - private final ClaimsBuilder expectedClaims; + int delimiterCount = 0; - private final Clock clock; + for (int i = 0; i < jwt.length(); i++) { + char c = jwt.charAt(i); - private final Set critical; + if (delimiterCount == 2) { + return !Character.isWhitespace(c) && c != SEPARATOR_CHAR; + } - private final long allowedClockSkewMillis; + if (c == SEPARATOR_CHAR) { + delimiterCount++; + } + } - //SigningKeyResolver will be removed for 1.0: - @SuppressWarnings("deprecation") - DefaultJwtParser(Provider provider, - SigningKeyResolver signingKeyResolver, - boolean unsecured, - boolean unsecuredDecompression, - Locator keyLocator, - Clock clock, - Set critical, - long allowedClockSkewMillis, - DefaultClaims expectedClaims, - Decoder base64UrlDecoder, - Deserializer> deserializer, - CompressionCodecResolver compressionCodecResolver, - Registry zipAlgs, - Registry> sigAlgs, - Registry> keyAlgs, - Registry encAlgs) { - this.provider = provider; - this.unsecured = unsecured; - this.unsecuredDecompression = unsecuredDecompression; - this.signingKeyResolver = signingKeyResolver; - this.keyLocator = Assert.notNull(keyLocator, "Key Locator cannot be null."); - this.clock = Assert.notNull(clock, "Clock cannot be null."); - this.critical = Collections.nullSafe(critical); - this.allowedClockSkewMillis = allowedClockSkewMillis; - this.expectedClaims = Jwts.claims().add(expectedClaims); - this.decoder = Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null."); - this.deserializer = Assert.notNull(deserializer, "JSON Deserializer cannot be null."); - this.sigAlgs = new IdLocator<>(DefaultHeader.ALGORITHM, sigAlgs, MISSING_JWS_ALG_MSG); - this.keyAlgs = new IdLocator<>(DefaultHeader.ALGORITHM, keyAlgs, MISSING_JWE_ALG_MSG); - this.encAlgs = new IdLocator<>(DefaultJweHeader.ENCRYPTION_ALGORITHM, encAlgs, MISSING_ENC_MSG); - this.zipAlgs = compressionCodecResolver != null ? new CompressionCodecLocator(compressionCodecResolver) : - new IdLocator<>(DefaultHeader.COMPRESSION_ALGORITHM, zipAlgs, null); + return false; } @Override - public boolean isSigned(CharSequence compact) { - if (!Strings.hasText(compact)) { - return false; + public Jwt parse(String jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException { + + // TODO, this logic is only need for a now deprecated code path + // remove this block in v1.0 (the equivalent is already in DefaultJwtParserBuilder) + if (this.deserializer == null) { + // try to find one based on the services available + // TODO: This util class will throw a UnavailableImplementationException here to retain behavior of previous version, remove in v1.0 + this.deserializer = LegacyServices.loadFirst(Deserializer.class); } - try { - final TokenizedJwt tokenized = jwtTokenizer.tokenize(new CharSequenceReader(compact)); - return !(tokenized instanceof TokenizedJwe) && Strings.hasText(tokenized.getDigest()); - } catch (MalformedJwtException e) { - return false; + + Assert.hasText(jwt, "JWT String argument cannot be null or empty."); + + if ("..".equals(jwt)) { + String msg = "JWT string '..' is missing a header."; + throw new MalformedJwtException(msg); } - } - private static boolean hasContentType(Header header) { - return header != null && Strings.hasText(header.getContentType()); - } + String base64UrlEncodedHeader = null; + String base64UrlEncodedPayload = null; + String base64UrlEncodedDigest = null; - private void verifySignature(final TokenizedJwt tokenized, final JwsHeader jwsHeader, final String alg, - @SuppressWarnings("deprecation") SigningKeyResolver resolver, Claims claims, Payload payload) { + int delimiterCount = 0; - Assert.notNull(resolver, "SigningKeyResolver instance cannot be null."); + StringBuilder sb = new StringBuilder(128); - SecureDigestAlgorithm algorithm; - try { - algorithm = (SecureDigestAlgorithm) sigAlgs.apply(jwsHeader); - } catch (UnsupportedJwtException e) { - //For backwards compatibility. TODO: remove this try/catch block for 1.0 and let UnsupportedJwtException propagate - String msg = "Unsupported signature algorithm '" + alg + "'"; - throw new SignatureException(msg, e); - } - Assert.stateNotNull(algorithm, "JWS Signature Algorithm cannot be null."); + for (char c : jwt.toCharArray()) { - //digitally signed, let's assert the signature: - Key key; - if (claims != null) { - key = resolver.resolveSigningKey(jwsHeader, claims); - } else { - key = resolver.resolveSigningKey(jwsHeader, payload.getBytes()); - } - if (key == null) { - String msg = "Cannot verify JWS signature: unable to locate signature verification key for JWS with header: " + jwsHeader; - throw new UnsupportedJwtException(msg); - } - Provider provider = ProviderKey.getProvider(key, this.provider); // extract if necessary - key = ProviderKey.getKey(key); // unwrap if necessary, MUST be called after ProviderKey.getProvider - Assert.stateNotNull(key, "ProviderKey cannot be null."); //ProviderKey impl doesn't allow null - if (key instanceof PrivateKey) { - throw new InvalidKeyException(PRIV_KEY_VERIFY_MSG); - } + if (c == SEPARATOR_CHAR) { - final byte[] signature = decode(tokenized.getDigest(), "JWS signature"); + CharSequence tokenSeq = Strings.clean(sb); + String token = tokenSeq != null ? tokenSeq.toString() : null; - //re-create the jwt part without the signature. This is what is needed for signature verification: - InputStream payloadStream = null; - InputStream verificationInput; - if (jwsHeader.isPayloadEncoded()) { - int len = tokenized.getProtected().length() + 1 + tokenized.getPayload().length(); - CharBuffer cb = CharBuffer.allocate(len); - cb.put(Strings.wrap(tokenized.getProtected())); - cb.put(SEPARATOR_CHAR); - cb.put(Strings.wrap(tokenized.getPayload())); - cb.rewind(); - ByteBuffer bb = StandardCharsets.US_ASCII.encode(cb); - bb.rewind(); - byte[] data = new byte[bb.remaining()]; - bb.get(data); - verificationInput = Streams.of(data); - } else { // b64 extension - ByteBuffer headerBuf = StandardCharsets.US_ASCII.encode(Strings.wrap(tokenized.getProtected())); - headerBuf.rewind(); - ByteBuffer buf = ByteBuffer.allocate(headerBuf.remaining() + 1); - buf.put(headerBuf); - buf.put((byte) SEPARATOR_CHAR); - buf.rewind(); - byte[] data = new byte[buf.remaining()]; - buf.get(data); - InputStream prefixStream = Streams.of(data); - payloadStream = payload.toInputStream(); - // We wrap the payloadStream here in an UncloseableInputStream to prevent the SequenceInputStream from - // closing it since we'll need to rewind/reset it if decompression is enabled - verificationInput = new SequenceInputStream(prefixStream, new UncloseableInputStream(payloadStream)); - } + if (delimiterCount == 0) { + base64UrlEncodedHeader = token; + } else if (delimiterCount == 1) { + base64UrlEncodedPayload = token; + } - try { - VerifySecureDigestRequest request = - new DefaultVerifySecureDigestRequest<>(verificationInput, provider, null, key, signature); - if (!algorithm.verify(request)) { - String msg = "JWT signature does not match locally computed signature. JWT validity cannot be " + - "asserted and should not be trusted."; - throw new SignatureException(msg); + delimiterCount++; + sb.setLength(0); + } else { + sb.append(c); } - } catch (WeakKeyException e) { - throw e; - } catch (InvalidKeyException | IllegalArgumentException e) { - String algId = algorithm.getId(); - String msg = "The parsed JWT indicates it was signed with the '" + algId + "' signature " + - "algorithm, but the provided " + key.getClass().getName() + " key may " + - "not be used to verify " + algId + " signatures. Because the specified " + - "key reflects a specific and expected algorithm, and the JWT does not reflect " + - "this algorithm, it is likely that the JWT was not expected and therefore should not be " + - "trusted. Another possibility is that the parser was provided the incorrect " + - "signature verification key, but this cannot be assumed for security reasons."; - throw new UnsupportedJwtException(msg, e); - } finally { - Streams.reset(payloadStream); } - } - @Override - public Jwt parse(Reader reader) { - Assert.notNull(reader, "Reader cannot be null."); - return parse(reader, Payload.EMPTY); - } - - private Jwt parse(Reader compact, Payload unencodedPayload) { - - Assert.notNull(compact, "Compact reader cannot be null."); - Assert.stateNotNull(unencodedPayload, "internal error: unencodedPayload is null."); - - final TokenizedJwt tokenized = jwtTokenizer.tokenize(compact); - final CharSequence base64UrlHeader = tokenized.getProtected(); - if (!Strings.hasText(base64UrlHeader)) { - String msg = "Compact JWT strings MUST always have a Base64Url protected header per " + - "https://tools.ietf.org/html/rfc7519#section-7.2 (steps 2-4)."; + if (delimiterCount != 2) { + String msg = "JWT strings must contain exactly 2 period characters. Found: " + delimiterCount; throw new MalformedJwtException(msg); } + if (sb.length() > 0) { + base64UrlEncodedDigest = sb.toString(); + } + // =============== Header ================= - final byte[] headerBytes = decode(base64UrlHeader, "protected header"); - Map m = deserialize(Streams.of(headerBytes), "protected header"); - Header header; - try { - header = tokenized.createHeader(m); - } catch (Exception e) { - String msg = "Invalid protected header: " + e.getMessage(); - throw new MalformedJwtException(msg, e); - } + Header header = null; - // https://tools.ietf.org/html/rfc7515#section-10.7 , second-to-last bullet point, note the use of 'always': - // - // * Require that the "alg" Header Parameter be carried in the JWS - // Protected Header. (This is always the case when using the JWS - // Compact Serialization and is the approach taken by CMS [RFC6211].) - // - final String alg = Strings.clean(header.getAlgorithm()); - if (!Strings.hasText(alg)) { - String msg = tokenized instanceof TokenizedJwe ? MISSING_JWE_ALG_MSG : MISSING_JWS_ALG_MSG; - throw new MalformedJwtException(msg); - } - final boolean unsecured = Jwts.SIG.NONE.getId().equalsIgnoreCase(alg); + CompressionCodec compressionCodec = null; - final CharSequence base64UrlDigest = tokenized.getDigest(); - final boolean hasDigest = Strings.hasText(base64UrlDigest); - if (unsecured) { - if (tokenized instanceof TokenizedJwe) { - throw new MalformedJwtException(JWE_NONE_MSG); + if (base64UrlEncodedHeader != null) { + byte[] bytes = base64UrlDecoder.decode(base64UrlEncodedHeader); + String origValue = new String(bytes, Strings.UTF_8); + Map m = (Map) readValue(origValue); + + if (base64UrlEncodedDigest != null) { + header = new DefaultJwsHeader(m); + } else { + header = new DefaultHeader(m); } - // Unsecured JWTs are disabled by default per the RFC: - if (!this.unsecured) { - String msg = UNSECURED_DISABLED_MSG_PREFIX + header; - throw new UnsupportedJwtException(msg); - } - if (hasDigest) { - throw new MalformedJwtException(JWS_NONE_SIG_MISMATCH_MSG); - } - if (header.containsKey(DefaultProtectedHeader.CRIT.getId())) { - String msg = String.format(CRIT_UNSECURED_MSG, header); - throw new MalformedJwtException(msg); - } - } else if (!hasDigest) { // something other than 'none'. Must have a digest component: - String fmt = tokenized instanceof TokenizedJwe ? MISSING_JWE_DIGEST_MSG_FMT : MISSING_JWS_DIGEST_MSG_FMT; - String msg = String.format(fmt, alg); - throw new MalformedJwtException(msg); + + compressionCodec = compressionCodecResolver.resolveCompressionCodec(header); } - // ----- crit assertions ----- - if (header instanceof ProtectedHeader) { - Set crit = Collections.nullSafe(((ProtectedHeader) header).getCritical()); - Set supportedCrit = this.critical; - String b64Id = DefaultJwsHeader.B64.getId(); - if (!unencodedPayload.isEmpty() && !this.critical.contains(b64Id)) { - // The application developer explicitly indicates they're using a B64 payload, so - // ensure that the B64 crit header is supported, even if they forgot to configure it on the - // parser builder: - supportedCrit = new LinkedHashSet<>(Collections.size(this.critical) + 1); - supportedCrit.add(DefaultJwsHeader.B64.getId()); - supportedCrit.addAll(this.critical); + + // =============== Body ================= + String payload = ""; // https://github.com/jwtk/jjwt/pull/540 + if (base64UrlEncodedPayload != null) { + byte[] bytes = base64UrlDecoder.decode(base64UrlEncodedPayload); + if (compressionCodec != null) { + bytes = compressionCodec.decompress(bytes); } - // assert any values per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11: - for (String name : crit) { - if (!header.containsKey(name)) { - String msg = String.format(CRIT_MISSING_MSG, name, name, header); - throw new MalformedJwtException(msg); - } - if (!supportedCrit.contains(name)) { - String msg = String.format(CRIT_UNSUPPORTED_MSG, name, name, header); - throw new UnsupportedJwtException(msg); - } - } + payload = new String(bytes, Strings.UTF_8); } - // =============== Payload ================= - final CharSequence payloadToken = tokenized.getPayload(); - Payload payload; - boolean integrityVerified = false; // only true after successful signature verification or AEAD decryption + Claims claims = null; - // check if b64 extension enabled: - final boolean payloadBase64UrlEncoded = !(header instanceof JwsHeader) || ((JwsHeader) header).isPayloadEncoded(); - if (payloadBase64UrlEncoded) { - // standard encoding, so decode it: - byte[] data = decode(tokenized.getPayload(), "payload"); - payload = new Payload(data, header.getContentType()); - } else { - // The JWT uses the b64 extension, and we already know the parser supports that extension at this point - // in the code execution path because of the ----- crit ----- assertions section above as well as the - // (JwsHeader).isPayloadEncoded() check - if (Strings.hasText(payloadToken)) { - // we need to verify what was in the token, otherwise it'd be a security issue if we ignored it - // and assumed the (likely safe) unencodedPayload value instead: - payload = new Payload(payloadToken, header.getContentType()); - } else { - //no payload token (a detached payload), so we need to ensure that they've specified the payload value: - if (unencodedPayload.isEmpty()) { - String msg = String.format(B64_MISSING_PAYLOAD, header); - throw new SignatureException(msg); - } - // otherwise, use the specified payload: - payload = unencodedPayload; - } + if (!payload.isEmpty() && payload.charAt(0) == '{' && payload.charAt(payload.length() - 1) == '}') { //likely to be json, parse it: + Map claimsMap = (Map) readValue(payload); + claims = new DefaultClaims(claimsMap); } - if (tokenized instanceof TokenizedJwe && payload.isEmpty()) { - // 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); - } + // =============== Signature ================= + if (base64UrlEncodedDigest != null) { //it is signed - validate the signature - byte[] iv = null; - byte[] tag = null; - if (tokenized instanceof TokenizedJwe) { + JwsHeader jwsHeader = (JwsHeader) header; - TokenizedJwe tokenizedJwe = (TokenizedJwe) tokenized; - JweHeader jweHeader = Assert.stateIsInstance(JweHeader.class, header, "Not a JweHeader. "); + SignatureAlgorithm algorithm = null; - byte[] cekBytes = Bytes.EMPTY; //ignored unless using an encrypted key algorithm - CharSequence base64Url = tokenizedJwe.getEncryptedKey(); - if (Strings.hasText(base64Url)) { - cekBytes = decode(base64Url, "JWE encrypted key"); - if (Bytes.isEmpty(cekBytes)) { - String msg = "Compact JWE string represents an encrypted key, but the key is empty."; - throw new MalformedJwtException(msg); + if (header != null) { + String alg = jwsHeader.getAlgorithm(); + if (Strings.hasText(alg)) { + algorithm = SignatureAlgorithm.forName(alg); } } - base64Url = tokenizedJwe.getIv(); - if (Strings.hasText(base64Url)) { - iv = decode(base64Url, "JWE Initialization Vector"); - } - if (Bytes.isEmpty(iv)) { - String msg = "Compact JWE strings must always contain an Initialization Vector."; + if (algorithm == null || algorithm == SignatureAlgorithm.NONE) { + //it is plaintext, but it has a signature. This is invalid: + String msg = "JWT string has a digest/signature, but the header does not reference a valid signature " + + "algorithm."; throw new MalformedJwtException(msg); } - // The AAD (Additional Authenticated Data) scheme for compact JWEs is to use the ASCII bytes of the - // raw base64url text as the AAD, and NOT the base64url-decoded bytes per - // https://www.rfc-editor.org/rfc/rfc7516.html#section-5.1, Step 14. - ByteBuffer buf = StandardCharsets.US_ASCII.encode(Strings.wrap(base64UrlHeader)); - final byte[] aadBytes = new byte[buf.remaining()]; - buf.get(aadBytes); - InputStream aad = Streams.of(aadBytes); - - 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 = decode(base64Url, "JWE AAD Authentication Tag"); - if (Bytes.isEmpty(tag)) { - String msg = "Compact JWE strings must always contain an AAD Authentication Tag."; - throw new MalformedJwtException(msg); + if (key != null && keyBytes != null) { + throw new IllegalStateException("A key object and key bytes cannot both be specified. Choose either."); + } else if ((key != null || keyBytes != null) && signingKeyResolver != null) { + String object = key != null ? "a key object" : "key bytes"; + throw new IllegalStateException("A signing key resolver and " + object + " cannot both be specified. Choose either."); } - String enc = jweHeader.getEncryptionAlgorithm(); - if (!Strings.hasText(enc)) { - throw new MalformedJwtException(MISSING_ENC_MSG); - } - final AeadAlgorithm encAlg = this.encAlgs.apply(jweHeader); - Assert.stateNotNull(encAlg, "JWE Encryption Algorithm cannot be null."); + //digitally signed, let's assert the signature: + Key key = this.key; - @SuppressWarnings("rawtypes") final KeyAlgorithm keyAlg = this.keyAlgs.apply(jweHeader); - Assert.stateNotNull(keyAlg, "JWE Key Algorithm cannot be null."); + if (key == null) { //fall back to keyBytes - Key key = this.keyLocator.locate(jweHeader); - if (key == null) { - String msg = "Cannot decrypt JWE payload: unable to locate key for JWE with header: " + jweHeader; - throw new UnsupportedJwtException(msg); - } - if (key instanceof PublicKey) { - throw new InvalidKeyException(PUB_KEY_DECRYPT_MSG); - } + byte[] keyBytes = this.keyBytes; - // extract key-specific provider if necessary; - Provider provider = ProviderKey.getProvider(key, this.provider); - key = ProviderKey.getKey(key); // this must be called after ProviderKey.getProvider - DecryptionKeyRequest request = - new DefaultDecryptionKeyRequest<>(cekBytes, provider, null, jweHeader, encAlg, key); - final SecretKey cek = keyAlg.getDecryptionKey(request); - if (cek == null) { - String msg = "The '" + keyAlg.getId() + "' JWE key algorithm did not return a decryption key. " + - "Unable to perform '" + encAlg.getId() + "' decryption."; - throw new IllegalStateException(msg); - } + if (Objects.isEmpty(keyBytes) && signingKeyResolver != null) { //use the signingKeyResolver + if (claims != null) { + key = signingKeyResolver.resolveSigningKey(jwsHeader, claims); + } else { + key = signingKeyResolver.resolveSigningKey(jwsHeader, payload); + } + } - // During decryption, the available Provider applies to the KeyAlgorithm, not the AeadAlgorithm, mostly - // because all JVMs support the standard AeadAlgorithms (especially with BouncyCastle in the classpath). - // As such, the provider here is intentionally omitted (null): - // TODO: add encProvider(Provider) builder method that applies to this request only? - InputStream ciphertext = payload.toInputStream(); - ByteArrayOutputStream plaintext = new ByteArrayOutputStream(8192); - DecryptAeadRequest dreq = new DefaultDecryptAeadRequest(ciphertext, cek, aad, iv, tag); - encAlg.decrypt(dreq, plaintext); - payload = new Payload(plaintext.toByteArray(), header.getContentType()); + if (!Objects.isEmpty(keyBytes)) { - integrityVerified = true; // AEAD performs integrity verification, so no exception = verified + Assert.isTrue(algorithm.isHmac(), + "Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance."); - } 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 payload, which is - // always safer: - JwsHeader jwsHeader = Assert.stateIsInstance(JwsHeader.class, header, "Not a JwsHeader. "); - verifySignature(tokenized, jwsHeader, alg, new LocatingKeyResolver(this.keyLocator), null, payload); - integrityVerified = true; // no exception means signature verified - } - - final CompressionAlgorithm compressionAlgorithm = zipAlgs.apply(header); - if (compressionAlgorithm != null) { - if (!integrityVerified) { - if (!payloadBase64UrlEncoded) { - String msg = String.format(B64_DECOMPRESSION_MSG, compressionAlgorithm.getId()); - throw new UnsupportedJwtException(msg); - } else if (!unsecuredDecompression) { - String msg = String.format(UNPROTECTED_DECOMPRESSION_MSG, compressionAlgorithm.getId()); - throw new UnsupportedJwtException(msg); + key = new SecretKeySpec(keyBytes, algorithm.getJcaName()); } } - payload = payload.decompress(compressionAlgorithm); - } - Claims claims = null; - byte[] payloadBytes = payload.getBytes(); - if (payload.isConsumable()) { + Assert.notNull(key, "A signing key must be specified if the specified JWT is digitally signed."); - InputStream in = payload.toInputStream(); + //re-create the jwt part without the signature. This is what needs to be signed for verification: + String jwtWithoutSignature = base64UrlEncodedHeader + SEPARATOR_CHAR; + if (base64UrlEncodedPayload != null) { + jwtWithoutSignature += base64UrlEncodedPayload; + } - if (!hasContentType(header)) { // If there is a content type set, then the application using JJWT is expected - // to convert the byte payload themselves based on this content type - // https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.10 : - // - // "This parameter is ignored by JWS implementations; any processing of this - // parameter is performed by the JWS application." - // - Map claimsMap = null; - try { - // if deserialization fails, we'll need to rewind to convert to a byte array. So if - // mark/reset isn't possible, we'll need to buffer: - if (!in.markSupported()) { - in = new BufferedInputStream(in); - in.mark(0); - } - claimsMap = deserialize(new UncloseableInputStream(in) /* Don't close in case we need to rewind */, "claims"); - } catch (DeserializationException | MalformedJwtException ignored) { // not JSON, treat it as a byte[] -// String msg = "Invalid claims: " + e.getMessage(); -// throw new MalformedJwtException(msg, e); - } finally { - Streams.reset(in); - } - if (claimsMap != null) { - try { - claims = new DefaultClaims(claimsMap); - } catch (Throwable t) { - String msg = "Invalid claims: " + t.getMessage(); - throw new MalformedJwtException(msg); - } - } + JwtSignatureValidator validator; + try { + algorithm.assertValidVerificationKey(key); //since 0.10.0: https://github.com/jwtk/jjwt/issues/334 + validator = createSignatureValidator(algorithm, key); + } catch (WeakKeyException e) { + throw e; + } catch (InvalidKeyException | IllegalArgumentException e) { + String algName = algorithm.getValue(); + String msg = "The parsed JWT indicates it was signed with the " + algName + " signature " + + "algorithm, but the specified signing key of type " + key.getClass().getName() + + " may not be used to validate " + algName + " signatures. Because the specified " + + "signing key reflects a specific and expected algorithm, and the JWT does not reflect " + + "this algorithm, it is likely that the JWT was not expected and therefore should not be " + + "trusted. Another possibility is that the parser was configured with the incorrect " + + "signing key, but this cannot be assumed for security reasons."; + throw new UnsupportedJwtException(msg, e); } - if (claims == null) { - // consumable, but not claims, so convert to byte array: - payloadBytes = Streams.bytes(in, "Unable to convert payload to byte array."); + + if (!validator.isValid(jwtWithoutSignature, base64UrlEncodedDigest)) { + String msg = "JWT signature does not match locally computed signature. JWT validity cannot be " + + "asserted and should not be trusted."; + throw new SignatureException(msg); } } - Jwt jwt; - Object body = claims != null ? claims : payloadBytes; - if (header instanceof JweHeader) { - jwt = new DefaultJwe<>((JweHeader) header, body, iv, tag); - } else if (hasDigest) { - JwsHeader jwsHeader = Assert.isInstanceOf(JwsHeader.class, header, "JwsHeader required."); - jwt = new DefaultJws<>(jwsHeader, body, base64UrlDigest.toString()); - } else { - //noinspection rawtypes - jwt = new DefaultJwt(header, body); - } - - // =============== Signature ================= - if (hasDigest && signingKeyResolver != null) { // TODO: remove for 1.0 - // A SigningKeyResolver has been configured, and due to it's API, we have to verify the signature after - // parsing the body. This can be a security risk, so it needs to be removed before 1.0 - JwsHeader jwsHeader = Assert.stateIsInstance(JwsHeader.class, header, "Not a JwsHeader. "); - verifySignature(tokenized, jwsHeader, alg, this.signingKeyResolver, claims, payload); - } - final boolean allowSkew = this.allowedClockSkewMillis > 0; //since 0.3: @@ -663,50 +429,57 @@ final Date now = this.clock.now(); long nowTime = now.getTime(); - // https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4 - // token MUST NOT be accepted on or after any specified exp time: + //https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.4 + //token MUST NOT be accepted on or after any specified exp time: Date exp = claims.getExpiration(); if (exp != null) { long maxTime = nowTime - this.allowedClockSkewMillis; Date max = allowSkew ? new Date(maxTime) : now; if (max.after(exp)) { - String expVal = DateFormats.formatIso8601(exp, true); - String nowVal = DateFormats.formatIso8601(now, true); + String expVal = DateFormats.formatIso8601(exp, false); + String nowVal = DateFormats.formatIso8601(now, false); - long differenceMillis = nowTime - exp.getTime(); + long differenceMillis = maxTime - exp.getTime(); - String msg = "JWT expired " + differenceMillis + " milliseconds ago at " + expVal + ". " + - "Current time: " + nowVal + ". Allowed clock skew: " + - this.allowedClockSkewMillis + " milliseconds."; + String msg = "JWT expired at " + expVal + ". Current time: " + nowVal + ", a difference of " + + differenceMillis + " milliseconds. Allowed clock skew: " + + this.allowedClockSkewMillis + " milliseconds."; throw new ExpiredJwtException(header, claims, msg); } } - // https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.5 - // token MUST NOT be accepted before any specified nbf time: + //https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.5 + //token MUST NOT be accepted before any specified nbf time: Date nbf = claims.getNotBefore(); if (nbf != null) { long minTime = nowTime + this.allowedClockSkewMillis; Date min = allowSkew ? new Date(minTime) : now; if (min.before(nbf)) { - String nbfVal = DateFormats.formatIso8601(nbf, true); - String nowVal = DateFormats.formatIso8601(now, true); + String nbfVal = DateFormats.formatIso8601(nbf, false); + String nowVal = DateFormats.formatIso8601(now, false); - long differenceMillis = nbf.getTime() - nowTime; + long differenceMillis = nbf.getTime() - minTime; - String msg = "JWT early by " + differenceMillis + " milliseconds before " + nbfVal + - ". Current time: " + nowVal + ". Allowed clock skew: " + - this.allowedClockSkewMillis + " milliseconds."; + String msg = "JWT must not be accepted before " + nbfVal + ". Current time: " + nowVal + + ", a difference of " + + differenceMillis + " milliseconds. Allowed clock skew: " + + this.allowedClockSkewMillis + " milliseconds."; throw new PrematureJwtException(header, claims, msg); } } validateExpectedClaims(header, claims); } - return jwt; + Object body = claims != null ? claims : payload; + + if (base64UrlEncodedDigest != null) { + return new DefaultJws<>((JwsHeader) header, body, base64UrlEncodedDigest); + } else { + return new DefaultJwt<>(header, body); + } } /** @@ -721,175 +494,134 @@ private void validateExpectedClaims(Header header, Claims claims) { - final Claims expected = expectedClaims.build(); + for (String expectedClaimName : expectedClaims.keySet()) { - for (String expectedClaimName : expected.keySet()) { - - Object expectedClaimValue = normalize(expected.get(expectedClaimName)); + Object expectedClaimValue = normalize(expectedClaims.get(expectedClaimName)); Object actualClaimValue = normalize(claims.get(expectedClaimName)); if (expectedClaimValue instanceof Date) { try { actualClaimValue = claims.get(expectedClaimName, Date.class); } catch (Exception e) { String msg = "JWT Claim '" + expectedClaimName + "' was expected to be a Date, but its value " + - "cannot be converted to a Date using current heuristics. Value: " + actualClaimValue; - throw new IncorrectClaimException(header, claims, expectedClaimName, expectedClaimValue, msg); + "cannot be converted to a Date using current heuristics. Value: " + actualClaimValue; + throw new IncorrectClaimException(header, claims, msg); } } + InvalidClaimException invalidClaimException = null; + if (actualClaimValue == null) { - boolean collection = expectedClaimValue instanceof Collection; - String msg = "Missing '" + expectedClaimName + "' claim. Expected value"; - if (collection) { - msg += "s: " + expectedClaimValue; - } else { - msg += ": " + expectedClaimValue; - } - throw new MissingClaimException(header, claims, expectedClaimName, expectedClaimValue, msg); - } else if (expectedClaimValue instanceof Collection) { - Collection expectedValues = (Collection) expectedClaimValue; - Collection actualValues = actualClaimValue instanceof Collection ? (Collection) actualClaimValue : - Collections.setOf(actualClaimValue); - for (Object expectedValue : expectedValues) { - if (!Collections.contains(actualValues.iterator(), expectedValue)) { - String msg = String.format(MISSING_EXPECTED_CLAIM_VALUE_MESSAGE_TEMPLATE, - expectedValue, expectedClaimName, actualValues); - throw new IncorrectClaimException(header, claims, expectedClaimName, expectedClaimValue, msg); - } - } - } else if (!expectedClaimValue.equals(actualClaimValue)) { - String msg = String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, - expectedClaimName, expectedClaimValue, actualClaimValue); - throw new IncorrectClaimException(header, claims, expectedClaimName, expectedClaimValue, msg); - } - } - } - @SuppressWarnings("deprecation") - @Override - public T parse(CharSequence compact, JwtHandler handler) { - return parse(compact, Payload.EMPTY).accept(handler); - } + String msg = String.format(ClaimJwtException.MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, + expectedClaimName, expectedClaimValue); - private Jwt parse(CharSequence compact, Payload unencodedPayload) { - Assert.hasText(compact, "JWT String argument cannot be null or empty."); - return parse(new CharSequenceReader(compact), unencodedPayload); - } + invalidClaimException = new MissingClaimException(header, claims, msg); - @Override - public Jwt parseContentJwt(CharSequence jwt) { - return parse(jwt).accept(Jwt.UNSECURED_CONTENT); - } + } else if (!expectedClaimValue.equals(actualClaimValue)) { - @Override - public Jwt parseClaimsJwt(CharSequence jwt) { - return parse(jwt).accept(Jwt.UNSECURED_CLAIMS); - } + String msg = String.format(ClaimJwtException.INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, + expectedClaimName, expectedClaimValue, actualClaimValue); - @Override - public Jws parseContentJws(CharSequence jws) { - return parseSignedContent(jws); - } + invalidClaimException = new IncorrectClaimException(header, claims, msg); + } - @Override - public Jws parseClaimsJws(CharSequence jws) { - return parseSignedClaims(jws); + if (invalidClaimException != null) { + invalidClaimException.setClaimName(expectedClaimName); + invalidClaimException.setClaimValue(expectedClaimValue); + throw invalidClaimException; + } + } } - @Override - public Jwt parseUnsecuredContent(CharSequence jwt) throws JwtException, IllegalArgumentException { - return parse(jwt).accept(Jwt.UNSECURED_CONTENT); + /* + * @since 0.5 mostly to allow testing overrides + */ + protected JwtSignatureValidator createSignatureValidator(SignatureAlgorithm alg, Key key) { + return new DefaultJwtSignatureValidator(alg, key, base64UrlDecoder); } @Override - public Jwt parseUnsecuredClaims(CharSequence jwt) throws JwtException, IllegalArgumentException { - return parse(jwt).accept(Jwt.UNSECURED_CLAIMS); - } + public T parse(String compact, JwtHandler handler) + throws ExpiredJwtException, MalformedJwtException, SignatureException { + Assert.notNull(handler, "JwtHandler argument cannot be null."); + Assert.hasText(compact, "JWT String argument cannot be null or empty."); - @Override - public Jws parseSignedContent(CharSequence compact) { - return parse(compact).accept(Jws.CONTENT); - } + Jwt jwt = parse(compact); - private Jws parseSignedContent(CharSequence jws, Payload unencodedPayload) { - return parse(jws, unencodedPayload).accept(Jws.CONTENT); + if (jwt instanceof Jws) { + Jws jws = (Jws) jwt; + Object body = jws.getBody(); + if (body instanceof Claims) { + return handler.onClaimsJws((Jws) jws); + } else { + return handler.onPlaintextJws((Jws) jws); + } + } else { + Object body = jwt.getBody(); + if (body instanceof Claims) { + return handler.onClaimsJwt((Jwt) jwt); + } else { + return handler.onPlaintextJwt((Jwt) jwt); + } + } } @Override - public Jws parseSignedClaims(CharSequence compact) { - return parse(compact).accept(Jws.CLAIMS); + public Jwt parsePlaintextJwt(String plaintextJwt) { + return parse(plaintextJwt, new JwtHandlerAdapter>() { + @Override + public Jwt onPlaintextJwt(Jwt jwt) { + return jwt; + } + }); } - private Jws parseSignedClaims(CharSequence jws, Payload unencodedPayload) { - unencodedPayload.setClaimsExpected(true); - return parse(jws, unencodedPayload).accept(Jws.CLAIMS); - } - @Override - public Jws parseSignedContent(CharSequence jws, byte[] unencodedPayload) { - Assert.notEmpty(unencodedPayload, "unencodedPayload argument cannot be null or empty."); - return parseSignedContent(jws, new Payload(unencodedPayload, null)); - } - - private static Payload payloadFor(InputStream in) { - if (in instanceof BytesInputStream) { - byte[] data = Streams.bytes(in, "Unable to obtain payload InputStream bytes."); - return new Payload(data, null); + public Jwt parseClaimsJwt(String claimsJwt) { + try { + return parse(claimsJwt, new JwtHandlerAdapter>() { + @Override + public Jwt onClaimsJwt(Jwt jwt) { + return jwt; + } + }); + } catch (IllegalArgumentException iae) { + throw new UnsupportedJwtException("Signed JWSs are not supported.", iae); } - //if (in.markSupported()) in.mark(0); - return new Payload(in, null); } @Override - public Jws parseSignedContent(CharSequence jws, InputStream unencodedPayload) { - Assert.notNull(unencodedPayload, "unencodedPayload InputStream cannot be null."); - return parseSignedContent(jws, payloadFor(unencodedPayload)); + public Jws parsePlaintextJws(String plaintextJws) { + try { + return parse(plaintextJws, new JwtHandlerAdapter>() { + @Override + public Jws onPlaintextJws(Jws jws) { + return jws; + } + }); + } catch (IllegalArgumentException iae) { + throw new UnsupportedJwtException("Signed JWSs are not supported.", iae); + } } @Override - public Jws parseSignedClaims(CharSequence jws, byte[] unencodedPayload) { - Assert.notEmpty(unencodedPayload, "unencodedPayload argument cannot be null or empty."); - return parseSignedClaims(jws, new Payload(unencodedPayload, null)); + public Jws parseClaimsJws(String claimsJws) { + return parse(claimsJws, new JwtHandlerAdapter>() { + @Override + public Jws onClaimsJws(Jws jws) { + return jws; + } + }); } - @Override - public Jws parseSignedClaims(CharSequence jws, InputStream unencodedPayload) { - Assert.notNull(unencodedPayload, "unencodedPayload InputStream cannot be null."); - byte[] bytes = Streams.bytes(unencodedPayload, - "Unable to obtain Claims bytes from unencodedPayload InputStream"); - return parseSignedClaims(jws, new Payload(bytes, null)); - } - - @Override - public Jwe parseEncryptedContent(CharSequence compact) throws JwtException { - return parse(compact).accept(Jwe.CONTENT); - } - - @Override - public Jwe parseEncryptedClaims(CharSequence compact) throws JwtException { - return parse(compact).accept(Jwe.CLAIMS); - } - - protected byte[] decode(CharSequence base64UrlEncoded, String name) { + @SuppressWarnings("unchecked") + protected Map readValue(String val) { try { - InputStream decoding = this.decoder.decode(Streams.of(Strings.utf8(base64UrlEncoded))); - return Streams.bytes(decoding, "Unable to Base64Url-decode input."); - } catch (Throwable t) { - // Don't disclose potentially-sensitive information per https://github.com/jwtk/jjwt/issues/824: - String value = "payload".equals(name) ? RedactedSupplier.REDACTED_VALUE : base64UrlEncoded.toString(); - String msg = "Invalid Base64Url " + name + ": " + value; - throw new MalformedJwtException(msg, t); + byte[] bytes = val.getBytes(Strings.UTF_8); + return deserializer.deserialize(bytes); + } catch (DeserializationException e) { + throw new MalformedJwtException("Unable to read JSON value: " + val, e); } } - - protected Map deserialize(InputStream in, final String name) { - try { - Reader reader = Streams.reader(in); - JsonObjectDeserializer deserializer = new JsonObjectDeserializer(this.deserializer, name); - return deserializer.apply(reader); - } finally { - Objects.nullSafeClose(in); - } - } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java (.../DefaultJwtParserBuilder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java (.../DefaultJwtParserBuilder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,46 +15,22 @@ */ package io.jsonwebtoken.impl; -import io.jsonwebtoken.ClaimsBuilder; +import io.jsonwebtoken.Claims; import io.jsonwebtoken.Clock; import io.jsonwebtoken.CompressionCodecResolver; import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.JwtParserBuilder; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.Locator; import io.jsonwebtoken.SigningKeyResolver; -import io.jsonwebtoken.impl.io.DelegateStringDecoder; -import io.jsonwebtoken.impl.io.StandardCompressionAlgorithms; -import io.jsonwebtoken.impl.lang.DefaultNestedCollection; -import io.jsonwebtoken.impl.lang.IdRegistry; -import io.jsonwebtoken.impl.lang.Services; -import io.jsonwebtoken.impl.security.ConstantKeyLocator; -import io.jsonwebtoken.impl.security.StandardEncryptionAlgorithms; -import io.jsonwebtoken.impl.security.StandardKeyAlgorithms; -import io.jsonwebtoken.impl.security.StandardSecureDigestAlgorithms; -import io.jsonwebtoken.io.CompressionAlgorithm; +import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver; import io.jsonwebtoken.io.Decoder; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.lang.Assert; -import io.jsonwebtoken.lang.Collections; -import io.jsonwebtoken.lang.NestedCollection; -import io.jsonwebtoken.lang.Registry; -import io.jsonwebtoken.security.AeadAlgorithm; -import io.jsonwebtoken.security.InvalidKeyException; -import io.jsonwebtoken.security.KeyAlgorithm; -import io.jsonwebtoken.security.Keys; -import io.jsonwebtoken.security.SecureDigestAlgorithm; +import io.jsonwebtoken.impl.lang.Services; -import javax.crypto.SecretKey; -import java.io.InputStream; import java.security.Key; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.PublicKey; import java.util.Date; import java.util.Map; -import java.util.Set; /** * @since 0.11.0 @@ -65,92 +41,44 @@ /** * To prevent overflow per Issue 583. - *

    + * * Package-protected on purpose to allow use in backwards-compatible {@link DefaultJwtParser} implementation. * TODO: enable private modifier on these two variables when deleting DefaultJwtParser */ static final long MAX_CLOCK_SKEW_MILLIS = Long.MAX_VALUE / MILLISECONDS_PER_SECOND; static final String MAX_CLOCK_SKEW_ILLEGAL_MSG = "Illegal allowedClockSkewMillis value: multiplying this " + - "value by 1000 to obtain the number of milliseconds would cause a numeric overflow."; + "value by 1000 to obtain the number of milliseconds would cause a numeric overflow."; - private Provider provider; + private byte[] keyBytes; - private boolean unsecured = false; + private Key key; - private boolean unsecuredDecompression = false; + private SigningKeyResolver signingKeyResolver; - private Locator keyLocator; + private CompressionCodecResolver compressionCodecResolver = new DefaultCompressionCodecResolver(); - @SuppressWarnings("deprecation") //TODO: remove for 1.0 - private SigningKeyResolver signingKeyResolver = null; + private Decoder base64UrlDecoder = Decoders.BASE64URL; - private Registry encAlgs = Jwts.ENC.get(); - - private Registry> keyAlgs = Jwts.KEY.get(); - - private Registry> sigAlgs = Jwts.SIG.get(); - - private Registry zipAlgs = Jwts.ZIP.get(); - - @SuppressWarnings("deprecation") - private CompressionCodecResolver compressionCodecResolver; - - @SuppressWarnings("deprecation") - private Decoder decoder = new DelegateStringDecoder(Decoders.BASE64URL); - private Deserializer> deserializer; - private final ClaimsBuilder expectedClaims = Jwts.claims(); + private Claims expectedClaims = new DefaultClaims(); private Clock clock = DefaultClock.INSTANCE; - private Set critical = Collections.emptySet(); - private long allowedClockSkewMillis = 0; - private Key signatureVerificationKey; - private Key decryptionKey; @Override - public JwtParserBuilder unsecured() { - this.unsecured = true; - return this; - } - - @Override - public JwtParserBuilder unsecuredDecompression() { - this.unsecuredDecompression = true; - return this; - } - - @Override - public JwtParserBuilder provider(Provider provider) { - this.provider = provider; - return this; - } - - @Override public JwtParserBuilder deserializeJsonWith(Deserializer> deserializer) { - return json(deserializer); - } - - @Override - public JwtParserBuilder json(Deserializer> reader) { - this.deserializer = Assert.notNull(reader, "JSON Deserializer cannot be null."); + Assert.notNull(deserializer, "deserializer cannot be null."); + this.deserializer = deserializer; return this; } - @SuppressWarnings("deprecation") @Override - public JwtParserBuilder base64UrlDecodeWith(final Decoder decoder) { - Assert.notNull(decoder, "decoder cannot be null."); - return b64Url(new DelegateStringDecoder(decoder)); - } - - @Override - public JwtParserBuilder b64Url(Decoder decoder) { - Assert.notNull(decoder, "decoder cannot be null."); - this.decoder = decoder; + public JwtParserBuilder base64UrlDecodeWith(Decoder base64UrlDecoder) { + Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null."); + this.base64UrlDecoder = base64UrlDecoder; return this; } @@ -168,7 +96,7 @@ @Override public JwtParserBuilder requireAudience(String audience) { - expectedClaims.audience().add(audience).and(); + expectedClaims.setAudience(audience); return this; } @@ -200,230 +128,78 @@ 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.add(claimName, value); + expectedClaims.put(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; } @Override - public NestedCollection critical() { - return new DefaultNestedCollection(this, this.critical) { - @Override - protected void changed() { - critical = Collections.asSet(getCollection()); - } - }; - } - - @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; } @Override public JwtParserBuilder setSigningKey(byte[] key) { - Assert.notEmpty(key, "signature verification key cannot be null or empty."); - return setSigningKey(Keys.hmacShaKeyFor(key)); + Assert.notEmpty(key, "signing key cannot be null or empty."); + this.keyBytes = key; + return this; } @Override public JwtParserBuilder setSigningKey(String base64EncodedSecretKey) { - Assert.hasText(base64EncodedSecretKey, "signature verification key cannot be null or empty."); - byte[] bytes = Decoders.BASE64.decode(base64EncodedSecretKey); - return setSigningKey(bytes); - } - - @Override - public JwtParserBuilder setSigningKey(final Key key) { - if (key instanceof SecretKey) { - return verifyWith((SecretKey) key); - } else if (key instanceof PublicKey) { - return verifyWith((PublicKey) key); - } - String msg = "JWS verification key must be either a SecretKey (for MAC algorithms) or a PublicKey " + - "(for Signature algorithms)."; - throw new InvalidKeyException(msg); - } - - @Override - public JwtParserBuilder verifyWith(SecretKey key) { - return verifyWith((Key) key); - } - - @Override - public JwtParserBuilder verifyWith(PublicKey key) { - return verifyWith((Key) key); - } - - private JwtParserBuilder verifyWith(Key key) { - if (key instanceof PrivateKey) { - throw new IllegalArgumentException(DefaultJwtParser.PRIV_KEY_VERIFY_MSG); - } - this.signatureVerificationKey = Assert.notNull(key, "signature verification key cannot be null."); + Assert.hasText(base64EncodedSecretKey, "signing key cannot be null or empty."); + this.keyBytes = Decoders.BASE64.decode(base64EncodedSecretKey); return this; } @Override - 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) { - if (key instanceof PublicKey) { - throw new IllegalArgumentException(DefaultJwtParser.PUB_KEY_DECRYPT_MSG); - } - this.decryptionKey = Assert.notNull(key, "decryption key cannot be null."); + public JwtParserBuilder setSigningKey(Key key) { + Assert.notNull(key, "signing key cannot be null."); + this.key = key; return this; } @Override - public NestedCollection zip() { - return new DefaultNestedCollection(this, this.zipAlgs.values()) { - @Override - protected void changed() { - zipAlgs = new IdRegistry<>(StandardCompressionAlgorithms.NAME, getCollection()); - } - }; - } - - @Override - public NestedCollection enc() { - return new DefaultNestedCollection(this, this.encAlgs.values()) { - @Override - public void changed() { - encAlgs = new IdRegistry<>(StandardEncryptionAlgorithms.NAME, getCollection()); - } - }; - } - - @Override - public NestedCollection, JwtParserBuilder> sig() { - return new DefaultNestedCollection, JwtParserBuilder>(this, this.sigAlgs.values()) { - @Override - public void changed() { - sigAlgs = new IdRegistry<>(StandardSecureDigestAlgorithms.NAME, getCollection()); - } - }; - } - - @Override - public NestedCollection, JwtParserBuilder> key() { - return new DefaultNestedCollection, JwtParserBuilder>(this, this.keyAlgs.values()) { - @Override - public void changed() { - keyAlgs = new IdRegistry<>(StandardKeyAlgorithms.NAME, getCollection()); - } - }; - } - - @SuppressWarnings("deprecation") //TODO: remove for 1.0 - @Override public JwtParserBuilder setSigningKeyResolver(SigningKeyResolver signingKeyResolver) { Assert.notNull(signingKeyResolver, "SigningKeyResolver cannot be null."); this.signingKeyResolver = signingKeyResolver; return this; } @Override - public JwtParserBuilder keyLocator(Locator keyLocator) { - this.keyLocator = Assert.notNull(keyLocator, "Key locator cannot be null."); + public JwtParserBuilder setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver) { + Assert.notNull(compressionCodecResolver, "compressionCodecResolver cannot be null."); + this.compressionCodecResolver = compressionCodecResolver; return this; } - @SuppressWarnings("deprecation") @Override - public JwtParserBuilder setCompressionCodecResolver(CompressionCodecResolver resolver) { - this.compressionCodecResolver = Assert.notNull(resolver, "CompressionCodecResolver cannot be null."); - return this; - } - - @Override public JwtParser build() { + // Only lookup the deserializer IF it is null. It is possible a Deserializer implementation was set + // that is NOT exposed as a service and no other implementations are available for lookup. if (this.deserializer == null) { - //noinspection unchecked - json(Services.get(Deserializer.class)); + // try to find one based on the services available: + this.deserializer = Services.loadFirst(Deserializer.class); } - if (this.signingKeyResolver != null && this.signatureVerificationKey != null) { - String msg = "Both a 'signingKeyResolver and a 'verifyWith' key cannot be configured. " + - "Choose either, or prefer `keyLocator` when possible."; - throw new IllegalStateException(msg); - } - if (this.keyLocator != null) { - if (this.signatureVerificationKey != null) { - String msg = "Both 'keyLocator' and a 'verifyWith' key cannot be configured. " + - "Prefer 'keyLocator' if possible."; - throw new IllegalStateException(msg); - } - if (this.decryptionKey != null) { - String msg = "Both 'keyLocator' and a 'decryptWith' key cannot be configured. " + - "Prefer 'keyLocator' if possible."; - throw new IllegalStateException(msg); - } - } - Locator keyLocator = this.keyLocator; // user configured default, don't overwrite to ensure further build() calls work as expected - if (keyLocator == null) { - keyLocator = new ConstantKeyLocator(this.signatureVerificationKey, this.decryptionKey); - } - - if (!unsecured && unsecuredDecompression) { - String msg = "'unsecuredDecompression' is only relevant if 'unsecured' is also " + - "configured. Please read the JavaDoc of both features before enabling either " + - "due to their security implications."; - throw new IllegalStateException(msg); - } - if (this.compressionCodecResolver != null && !Jwts.ZIP.get().equals(this.zipAlgs)) { - String msg = "Both 'zip()' and 'compressionCodecResolver' " + - "cannot be configured. Choose either."; - throw new IllegalStateException(msg); - } - - // Invariants. If these are ever violated, it's an error in this class implementation: - Assert.stateNotNull(keyLocator, "Key locator should never be null."); - - final DefaultClaims expClaims = (DefaultClaims) this.expectedClaims.build(); - - return new DefaultJwtParser( - provider, - signingKeyResolver, - unsecured, - unsecuredDecompression, - keyLocator, - clock, - critical, - allowedClockSkewMillis, - expClaims, - decoder, - deserializer, - compressionCodecResolver, - zipAlgs, - sigAlgs, - keyAlgs, - encAlgs - ); + return new ImmutableJwtParser( + new DefaultJwtParser(signingKeyResolver, + key, + keyBytes, + clock, + allowedClockSkewMillis, + expectedClaims, + base64UrlDecoder, + deserializer, + compressionCodecResolver)); } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultMutableJweHeader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultProtectedHeader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultProtectedJwt.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultTextCodecFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultTokenizedJwe.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DefaultTokenizedJwt.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DelegateAudienceCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/DelegatingClaimsMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/FixedClock.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/FixedClock.java (.../FixedClock.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/FixedClock.java (.../FixedClock.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -47,16 +47,6 @@ this.now = now; } - /** - * Creates a new fixed clock using the specified seed timestamp. All calls to - * {@link #now now()} will always return this seed Date. - * - * @param timeInMillis the specified Date in milliseconds to always return from all calls to {@link #now now()}. - */ - public FixedClock(long timeInMillis) { - this(new Date(timeInMillis)); - } - @Override public Date now() { return this.now; Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/IdLocator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/ImmutableJwtParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/JwtMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/JwtTokenizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/ParameterMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/Payload.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/TextCodecFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/TokenizedJwe.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/TokenizedJwt.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/X509Context.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/AbstractCompressionAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/AbstractCompressionCodec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/CompressionCodecs.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/DeflateCompressionAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/DeflateCompressionCodec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/GzipCompressionAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/compression/GzipCompressionCodec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/DefaultSignerFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/JwtSignatureValidator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/JwtSigner.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/MacProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/MacSigner.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/MacValidator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/RsaProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/RsaSignatureValidator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/RsaSigner.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/SignatureProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/SignatureValidator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/SignatureValidatorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/Signer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/crypto/SignerFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/AbstractParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/AbstractParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/Base64Codec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/Base64InputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/Base64OutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/Base64UrlStreamEncoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/BaseNCodec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/BaseNCodecInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/BaseNCodecOutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/ByteBase64UrlStreamEncoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/BytesInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/CharSequenceReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/ClosedInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/Codec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/CodecPolicy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/ConvertingParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/CountingInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/DecodingInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/DelegateStringDecoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/EncodingOutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/FilteredInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/FilteredOutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/JsonObjectDeserializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/NamedSerializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/StandardCompressionAlgorithms.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/Streams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/TeeOutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/io/UncloseableInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/BiConsumer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/BigIntegerUBytesConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Bytes.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/CheckedFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/CheckedSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/CollectionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/CompactMediaTypeIdConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/CompoundConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/ConstantFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Converter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Converters.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DefaultCollectionMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DefaultNestedCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DefaultParameter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DefaultParameterBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DefaultRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DelegatingCheckedFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DelegatingMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/DelegatingMapMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/EncodedObjectConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/FormattedStringFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/FormattedStringSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Function.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Functions.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/IdRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/JwtDateConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/LegacyServices.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/LocatorFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Nameable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/NullSafeConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/OptionalMethodInvoker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Parameter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/ParameterBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/ParameterReadable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Parameters.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/PositiveIntegerConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/PropagatingExceptionFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/RedactedSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/RedactedValueConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/ReflectionFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/RequiredBitLengthConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/RequiredParameterReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/RequiredTypeConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Services.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Services.java (.../Services.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/Services.java (.../Services.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,24 +15,22 @@ */ package io.jsonwebtoken.impl.lang; -import io.jsonwebtoken.lang.Arrays; import io.jsonwebtoken.lang.Assert; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.ServiceLoader; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; +import static io.jsonwebtoken.lang.Collections.arrayToList; + /** * Helper class for loading services from the classpath, using a {@link ServiceLoader}. Decouples loading logic for * better separation of concerns and testability. */ public final class Services { - private static final ConcurrentMap, Object> SERVICES = new ConcurrentHashMap<>(); - - private static final List CLASS_LOADER_ACCESSORS = Arrays.asList(new ClassLoaderAccessor[]{ + private static final List CLASS_LOADER_ACCESSORS = arrayToList(new ClassLoaderAccessor[] { new ClassLoaderAccessor() { @Override public ClassLoader getClassLoader() { @@ -53,58 +51,66 @@ } }); - private Services() { - } + private Services() {} /** - * Returns the first available implementation for the given SPI class, checking an internal thread-safe cache first, - * and, if not found, using a {@link ServiceLoader} to find implementations. When multiple implementations are - * available it will return the first one that it encounters. There is no guarantee with regard to ordering. + * Loads and instantiates all service implementation of the given SPI class and returns them as a List. * * @param spi The class of the Service Provider Interface * @param The type of the SPI - * @return The first available instance of the service. - * @throws UnavailableImplementationException When no implementation of the SPI class can be found. - * @since 0.12.4 + * @return An unmodifiable list with an instance of all available implementations of the SPI. No guarantee is given + * on the order of implementations, if more than one. */ - public static T get(Class spi) { - // TODO: JDK8, replace this find/putIfAbsent logic with ConcurrentMap.computeIfAbsent - T instance = findCached(spi); - if (instance == null) { - instance = loadFirst(spi); // throws UnavailableImplementationException if not found, which is what we want - SERVICES.putIfAbsent(spi, instance); // cache if not already cached + public static List loadAll(Class spi) { + Assert.notNull(spi, "Parameter 'spi' must not be null."); + + for (ClassLoaderAccessor classLoaderAccessor : CLASS_LOADER_ACCESSORS) { + List implementations = loadAll(spi, classLoaderAccessor.getClassLoader()); + if (!implementations.isEmpty()) { + return Collections.unmodifiableList(implementations); + } } - return instance; + + throw new UnavailableImplementationException(spi); } - private static T findCached(Class spi) { - Assert.notNull(spi, "Service interface cannot be null."); - Object obj = SERVICES.get(spi); - if (obj != null) { - return Assert.isInstanceOf(spi, obj, "Unexpected cached service implementation type."); + private static List loadAll(Class spi, ClassLoader classLoader) { + ServiceLoader serviceLoader = ServiceLoader.load(spi, classLoader); + List implementations = new ArrayList<>(); + for (T implementation : serviceLoader) { + implementations.add(implementation); } - return null; + return implementations; } - private static T loadFirst(Class spi) { - for (ClassLoaderAccessor accessor : CLASS_LOADER_ACCESSORS) { - ServiceLoader loader = ServiceLoader.load(spi, accessor.getClassLoader()); - Assert.stateNotNull(loader, "JDK ServiceLoader#load should never return null."); - Iterator i = loader.iterator(); - Assert.stateNotNull(i, "JDK ServiceLoader#iterator() should never return null."); - if (i.hasNext()) { - return i.next(); + /** + * Loads the first available implementation the given SPI class from the classpath. Uses the {@link ServiceLoader} + * to find implementations. When multiple implementations are available it will return the first one that it + * encounters. There is no guarantee with regard to ordering. + * + * @param spi The class of the Service Provider Interface + * @param The type of the SPI + * @return A new instance of the service. + * @throws UnavailableImplementationException When no implementation the SPI is available on the classpath. + */ + public static T loadFirst(Class spi) { + Assert.notNull(spi, "Parameter 'spi' must not be null."); + + for (ClassLoaderAccessor classLoaderAccessor : CLASS_LOADER_ACCESSORS) { + T result = loadFirst(spi, classLoaderAccessor.getClassLoader()); + if (result != null) { + return result; } } throw new UnavailableImplementationException(spi); } - /** - * Clears internal cache of service singletons. This is useful when testing, or for applications that dynamically - * change classloaders. - */ - public static void reload() { - SERVICES.clear(); + private static T loadFirst(Class spi, ClassLoader classLoader) { + ServiceLoader serviceLoader = ServiceLoader.load(spi, classLoader); + if (serviceLoader.iterator().hasNext()) { + return serviceLoader.iterator().next(); + } + return null; } private interface ClassLoaderAccessor { Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/StringRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/UnavailableImplementationException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/UnavailableImplementationException.java (.../UnavailableImplementationException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/UnavailableImplementationException.java (.../UnavailableImplementationException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,17 +17,13 @@ /** * Exception indicating that no implementation of an jjwt-api SPI was found on the classpath. - * * @since 0.11.0 */ public final class UnavailableImplementationException extends RuntimeException { - private static final String DEFAULT_NOT_FOUND_MESSAGE = "Unable to find an implementation for %s using " + - "java.util.ServiceLoader. Ensure you include a backing implementation .jar in the classpath, " + - "for example jjwt-jackson.jar, jjwt-gson.jar or jjwt-orgjson.jar, or your own .jar for " + - "custom implementations."; + private static final String DEFAULT_NOT_FOUND_MESSAGE = "Unable to find an implementation for %s using java.util.ServiceLoader. Ensure you include a backing implementation .jar in the classpath, for example jjwt-impl.jar, or your own .jar for custom implementations."; - UnavailableImplementationException(final Class klass) { + UnavailableImplementationException(final Class klass) { super(String.format(DEFAULT_NOT_FOUND_MESSAGE, klass)); } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/lang/UriStringConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractAsymmetricJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractAsymmetricJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractCurve.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractEcJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractFamilyJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractJwkParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractSecureDigestAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractSecurityBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AbstractSignatureAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AesAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AesGcmKeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AesWrapKeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/AsymmetricJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ConcatKDF.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ConstantKeyLocator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/CryptoAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultAeadRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultAeadResult.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultDecryptAeadRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultDecryptionKeyRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultDynamicJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultEcPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultEcPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultHashAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultJwkContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultJwkParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultJwkSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultJwkSetBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultJwkSetParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultJwkThumbprint.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyOperation.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyOperationBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyOperationPolicy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyOperationPolicyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyPair.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyPairBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyResult.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultKeyUseStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultMessage.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultOctetPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultOctetPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultRsaPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultRsaPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultSecretJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultSecretKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultSecureRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultVerifyDigestRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DefaultVerifySecureDigestRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DirectKeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/DispatchingJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ECCurve.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EcPrivateJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EcPublicJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EcSignatureAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EcdhKeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EdSignatureAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EdwardsCurve.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/EdwardsPublicKeyDeriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/FamilyJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/FieldElementConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/GcmAesAeadAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/HmacAesAeadAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JcaTemplate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkBuilderSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkDeserializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkSetConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwkSetDeserializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwksBridge.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/JwtX509StringConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/KeyOperationConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/KeyPairs.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/KeyUsage.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/KeyUseStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/KeysBridge.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/LocatingKeyResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/NamedParameterSpecValueFinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/NoneSignatureAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/OctetJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/OctetPrivateJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/OctetPublicJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/PasswordSpec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/PrivateECKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ProvidedKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ProvidedPrivateKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ProvidedSecretKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ProviderKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ProviderPrivateKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/ProviderSecretKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/Providers.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/RSAOtherPrimeInfoConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/RandomSecretKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/Randoms.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/RsaPrivateJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/RsaPublicJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/SecretJwkFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/StandardCurves.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/StandardEncryptionAlgorithms.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/StandardHashAlgorithms.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/StandardKeyOperations.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/StandardSecureDigestAlgorithms.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/impl/security/X509BuilderSupport.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/AbstractDeserializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/AbstractSerializer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64.java (.../Base64.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64.java (.../Base64.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -111,7 +111,7 @@ // Encode even 24-bits for (int s = 0, d = 0, cc = 0; s < eLen; ) { - // Copy next three bytes into lower 24 bits of int, paying attention to sign. + // Copy next three bytes into lower 24 bits of int, paying attension to sign. int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); // Encode the int into four chars @@ -224,41 +224,40 @@ } /** - * Decodes a BASE64-encoded {@code CharSequence} that is known to be reasonably well formatted. The preconditions - * are:
    - * + The sequence must have a line length of 76 chars OR no line separators at all (one line).
    + * Decodes a BASE64 encoded char array that is known to be reasonably well formatted. The preconditions are:
    + * + The array must have a line length of 76 chars OR no line separators at all (one line).
    * + Line separator must be "\r\n", as specified in RFC 2045 - * + The sequence must not contain illegal characters within the encoded string
    - * + The sequence CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
    + * + The array must not contain illegal characters within the encoded string
    + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
    * - * @param seq The source sequence. Length 0 will return an empty array. null will throw an exception. + * @param sArr The source array. Length 0 will return an empty array. null will throw an exception. * @return The decoded array of bytes. May be of length 0. * @throws DecodingException on illegal input */ - byte[] decodeFast(CharSequence seq) throws DecodingException { + final byte[] decodeFast(char[] sArr) throws DecodingException { // Check special case - int sLen = seq != null ? seq.length() : 0; + int sLen = sArr != null ? sArr.length : 0; if (sLen == 0) { return new byte[0]; } int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. // Trim illegal chars from start - while (sIx < eIx && IALPHABET[seq.charAt(sIx)] < 0) { + while (sIx < eIx && IALPHABET[sArr[sIx]] < 0) { sIx++; } // Trim illegal chars from end - while (eIx > 0 && IALPHABET[seq.charAt(eIx)] < 0) { + while (eIx > 0 && IALPHABET[sArr[eIx]] < 0) { eIx--; } // get the padding count (=) (0, 1 or 2) - int pad = seq.charAt(eIx) == '=' ? (seq.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. int cCnt = eIx - sIx + 1; // Content count including possible separators - int sepCnt = sLen > 76 ? (seq.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes byte[] dArr = new byte[len]; // Preallocate byte[] of exact length @@ -268,7 +267,7 @@ for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) { // Assemble three bytes into an int from four "valid" characters. - int i = ctoi(seq.charAt(sIx++)) << 18 | ctoi(seq.charAt(sIx++)) << 12 | ctoi(seq.charAt(sIx++)) << 6 | ctoi(seq.charAt(sIx++)); + int i = ctoi(sArr[sIx++]) << 18 | ctoi(sArr[sIx++]) << 12 | ctoi(sArr[sIx++]) << 6 | ctoi(sArr[sIx++]); // Add the bytes dArr[d++] = (byte) (i >> 16); @@ -286,7 +285,7 @@ // Decode last 1-3 bytes (incl '=') into 1-3 bytes int i = 0; for (int j = 0; sIx <= eIx - pad; j++) { - i |= ctoi(seq.charAt(sIx++)) << (18 - j * 6); + i |= ctoi(sArr[sIx++]) << (18 - j * 6); } for (int r = 16; d < len; r -= 8) { @@ -340,7 +339,7 @@ // Encode even 24-bits for (int s = sOff, d = 0, cc = 0; s < sOff + eLen; ) { - // Copy next three bytes into lower 24 bits of int, paying attention to sign. + // Copy next three bytes into lower 24 bits of int, paying attension to sign. int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); // Encode the int into four chars @@ -405,7 +404,7 @@ } } - // Check so that legal chars (including '=') are evenly divisible by 4 as specified in RFC 2045. + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. if ((sLen - sepCnt) % 4 != 0) { return null; } @@ -448,7 +447,7 @@ /* - * Decodes a BASE64 encoded byte array that is known to be reasonably well formatted. The method is about twice as + * Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as * fast as {@link #decode(byte[])}. The preconditions are:
    * + The array must have a line length of 76 chars OR no line separators at all (one line).
    * + Line separator must be "\r\n", as specified in RFC 2045 @@ -534,7 +533,7 @@ * little faster. * @return A BASE64 encoded array. Never null. */ - String encodeToString(byte[] sArr, boolean lineSep) { + final String encodeToString(byte[] sArr, boolean lineSep) { // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower. return new String(encodeToChar(sArr, lineSep)); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Decoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Decoder.java (.../Base64Decoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Decoder.java (.../Base64Decoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,12 +18,9 @@ import io.jsonwebtoken.lang.Assert; /** - * Very fast Base64 decoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - * * @since 0.10.0 */ -class Base64Decoder extends Base64Support implements Decoder { +class Base64Decoder extends Base64Support implements Decoder { Base64Decoder() { super(Base64.DEFAULT); @@ -34,8 +31,8 @@ } @Override - public byte[] decode(CharSequence s) throws DecodingException { + public byte[] decode(String s) throws DecodingException { Assert.notNull(s, "String argument cannot be null"); - return this.base64.decodeFast(s); + return this.base64.decodeFast(s.toCharArray()); } } \ No newline at end of file Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Encoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Encoder.java (.../Base64Encoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Encoder.java (.../Base64Encoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,15 +18,12 @@ import io.jsonwebtoken.lang.Assert; /** - * Very fast Base64 encoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - * * @since 0.10.0 */ class Base64Encoder extends Base64Support implements Encoder { Base64Encoder() { - this(Base64.DEFAULT); + super(Base64.DEFAULT); } Base64Encoder(Base64 base64) { Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Support.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Support.java (.../Base64Support.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64Support.java (.../Base64Support.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,8 +18,6 @@ import io.jsonwebtoken.lang.Assert; /** - * Parent class for Base64 encoders and decoders. - * * @since 0.10.0 */ class Base64Support { Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64UrlDecoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64UrlDecoder.java (.../Base64UrlDecoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64UrlDecoder.java (.../Base64UrlDecoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,9 +16,6 @@ package io.jsonwebtoken.io; /** - * Very fast Base64Url decoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - * * @since 0.10.0 */ class Base64UrlDecoder extends Base64Decoder { Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64UrlEncoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64UrlEncoder.java (.../Base64UrlEncoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Base64UrlEncoder.java (.../Base64UrlEncoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,9 +16,6 @@ package io.jsonwebtoken.io; /** - * Very fast Base64Url encoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - * * @since 0.10.0 */ class Base64UrlEncoder extends Base64Encoder { Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/CodecException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/CodecException.java (.../CodecException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/CodecException.java (.../CodecException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,27 +16,14 @@ package io.jsonwebtoken.io; /** - * An exception thrown when encountering a problem during encoding or decoding. - * * @since 0.10.0 */ public class CodecException extends IOException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public CodecException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public CodecException(String message, Throwable cause) { super(message, cause); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/CompressionAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Decoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Decoder.java (.../Decoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Decoder.java (.../Decoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,20 +16,9 @@ package io.jsonwebtoken.io; /** - * A decoder converts an already-encoded data value to a desired data type. - * - * @param decoding input type - * @param decoding output type * @since 0.10.0 */ public interface Decoder { - /** - * Convert the specified encoded data value into the desired data type. - * - * @param t the encoded data - * @return the resulting expected data - * @throws DecodingException if there is a problem during decoding. - */ R decode(T t) throws DecodingException; } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Decoders.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Decoders.java (.../Decoders.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Decoders.java (.../Decoders.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,26 +16,13 @@ package io.jsonwebtoken.io; /** - * Constant definitions for various decoding algorithms. - * - * @see #BASE64 - * @see #BASE64URL * @since 0.10.0 */ public final class Decoders { - /** - * Very fast Base64 decoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - */ - public static final Decoder BASE64 = new ExceptionPropagatingDecoder<>(new Base64Decoder()); + public static final Decoder BASE64 = new ExceptionPropagatingDecoder<>(new Base64Decoder()); + public static final Decoder BASE64URL = new ExceptionPropagatingDecoder<>(new Base64UrlDecoder()); - /** - * Very fast Base64Url decoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - */ - public static final Decoder BASE64URL = new ExceptionPropagatingDecoder<>(new Base64UrlDecoder()); - private Decoders() { //prevent instantiation } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/DecodingException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/DecodingException.java (.../DecodingException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/DecodingException.java (.../DecodingException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,27 +16,14 @@ package io.jsonwebtoken.io; /** - * An exception thrown when encountering a problem during decoding. - * * @since 0.10.0 */ public class DecodingException extends CodecException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public DecodingException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public DecodingException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/DeserializationException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/DeserializationException.java (.../DeserializationException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/DeserializationException.java (.../DeserializationException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,27 +16,14 @@ package io.jsonwebtoken.io; /** - * Exception thrown when reconstituting a serialized byte array into a Java object. - * * @since 0.10.0 */ public class DeserializationException extends SerialException { - /** - * Creates a new instance with the specified explanation message. - * - * @param msg the message explaining why the exception is thrown. - */ public DeserializationException(String msg) { super(msg); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public DeserializationException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Deserializer.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Deserializer.java (.../Deserializer.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Deserializer.java (.../Deserializer.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,34 +15,10 @@ */ package io.jsonwebtoken.io; -import java.io.Reader; - /** - * A {@code Deserializer} is able to convert serialized byte streams into Java objects. - * - * @param the type of object to be returned as a result of deserialization. * @since 0.10.0 */ public interface Deserializer { - /** - * Convert the specified formatted data byte array into a Java object. - * - * @param bytes the formatted data byte array to convert - * @return the reconstituted Java object - * @throws DeserializationException if there is a problem converting the byte array to an object. - * @deprecated since 0.12.0 in favor of {@link #deserialize(Reader)} - */ - @Deprecated T deserialize(byte[] bytes) throws DeserializationException; - - /** - * Reads the specified character stream and returns the corresponding Java object. - * - * @param reader the reader to use to read the character stream - * @return the deserialized Java object - * @throws DeserializationException if there is a problem reading the stream or creating the expected Java object - * @since 0.12.0 - */ - T deserialize(Reader reader) throws DeserializationException; } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Encoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Encoder.java (.../Encoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Encoder.java (.../Encoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,20 +16,9 @@ package io.jsonwebtoken.io; /** - * An encoder converts data of one type into another formatted data value. - * - * @param the type of data to convert - * @param the type of the resulting formatted data * @since 0.10.0 */ public interface Encoder { - /** - * Convert the specified data into another formatted data value. - * - * @param t the data to convert - * @return the resulting formatted data value - * @throws EncodingException if there is a problem during encoding - */ R encode(T t) throws EncodingException; } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Encoders.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Encoders.java (.../Encoders.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Encoders.java (.../Encoders.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,24 +16,11 @@ package io.jsonwebtoken.io; /** - * Constant definitions for various encoding algorithms. - * - * @see #BASE64 - * @see #BASE64URL * @since 0.10.0 */ public final class Encoders { - /** - * Very fast Base64 encoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - */ public static final Encoder BASE64 = new ExceptionPropagatingEncoder<>(new Base64Encoder()); - - /** - * Very fast Base64Url encoder guaranteed to - * work in all >= Java 7 JDK and Android environments. - */ public static final Encoder BASE64URL = new ExceptionPropagatingEncoder<>(new Base64UrlEncoder()); private Encoders() { //prevent instantiation Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/EncodingException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/EncodingException.java (.../EncodingException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/EncodingException.java (.../EncodingException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,18 +16,10 @@ package io.jsonwebtoken.io; /** - * An exception thrown when encountering a problem during encoding. - * * @since 0.10.0 */ public class EncodingException extends CodecException { - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public EncodingException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ExceptionPropagatingDecoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ExceptionPropagatingDecoder.java (.../ExceptionPropagatingDecoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ExceptionPropagatingDecoder.java (.../ExceptionPropagatingDecoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,33 +18,17 @@ import io.jsonwebtoken.lang.Assert; /** - * Decoder that ensures any exceptions thrown that are not {@link DecodingException}s are wrapped - * and re-thrown as a {@code DecodingException}. - * * @since 0.10.0 */ class ExceptionPropagatingDecoder implements Decoder { private final Decoder decoder; - /** - * Creates a new instance, wrapping the specified {@code decoder} to invoke during {@link #decode(Object)}. - * - * @param decoder the decoder to wrap and call during {@link #decode(Object)} - */ ExceptionPropagatingDecoder(Decoder decoder) { Assert.notNull(decoder, "Decoder cannot be null."); this.decoder = decoder; } - /** - * Decode the specified encoded data, delegating to the wrapped Decoder, wrapping any - * non-{@link DecodingException} as a {@code DecodingException}. - * - * @param t the encoded data - * @return the decoded data - * @throws DecodingException if there is an unexpected problem during decoding. - */ @Override public R decode(T t) throws DecodingException { Assert.notNull(t, "Decode argument cannot be null."); Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java (.../ExceptionPropagatingEncoder.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java (.../ExceptionPropagatingEncoder.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,33 +18,17 @@ import io.jsonwebtoken.lang.Assert; /** - * Encoder that ensures any exceptions thrown that are not {@link EncodingException}s are wrapped - * and re-thrown as a {@code EncodingException}. - * * @since 0.10.0 */ class ExceptionPropagatingEncoder implements Encoder { private final Encoder encoder; - /** - * Creates a new instance, wrapping the specified {@code encoder} to invoke during {@link #encode(Object)}. - * - * @param encoder the encoder to wrap and call during {@link #encode(Object)} - */ ExceptionPropagatingEncoder(Encoder encoder) { Assert.notNull(encoder, "Encoder cannot be null."); this.encoder = encoder; } - /** - * Encoded the specified data, delegating to the wrapped Encoder, wrapping any - * non-{@link EncodingException} as an {@code EncodingException}. - * - * @param t the data to encode - * @return the encoded data - * @throws EncodingException if there is an unexpected problem during encoding. - */ @Override public R encode(T t) throws EncodingException { Assert.notNull(t, "Encode argument cannot be null."); Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/IOException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/IOException.java (.../IOException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/IOException.java (.../IOException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,28 +18,14 @@ import io.jsonwebtoken.JwtException; /** - * JJWT's base exception for problems during data input or output operations, such as serialization, - * deserialization, marshalling, unmarshalling, etc. - * * @since 0.10.0 */ public class IOException extends JwtException { - /** - * Creates a new instance with the specified explanation message. - * - * @param msg the message explaining why the exception is thrown. - */ public IOException(String msg) { super(msg); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public IOException(String message, Throwable cause) { super(message, cause); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Parser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/ParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/SerialException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/SerialException.java (.../SerialException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/SerialException.java (.../SerialException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,27 +16,14 @@ package io.jsonwebtoken.io; /** - * An exception thrown during serialization or deserialization. - * * @since 0.10.0 */ public class SerialException extends IOException { - /** - * Creates a new instance with the specified explanation message. - * - * @param msg the message explaining why the exception is thrown. - */ public SerialException(String msg) { super(msg); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public SerialException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/SerializationException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/SerializationException.java (.../SerializationException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/SerializationException.java (.../SerializationException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,27 +16,14 @@ package io.jsonwebtoken.io; /** - * Exception thrown when converting a Java object to a formatted byte array. - * * @since 0.10.0 */ public class SerializationException extends SerialException { - /** - * Creates a new instance with the specified explanation message. - * - * @param msg the message explaining why the exception is thrown. - */ public SerializationException(String msg) { super(msg); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public SerializationException(String message, Throwable cause) { super(message, cause); } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Serializer.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Serializer.java (.../Serializer.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/io/Serializer.java (.../Serializer.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,37 +15,11 @@ */ package io.jsonwebtoken.io; -import java.io.OutputStream; - /** - * A {@code Serializer} is able to convert a Java object into a formatted byte stream. It is expected this byte stream - * can be reconstituted back into a Java object with a matching {@link Deserializer}. - * - * @param The type of object to serialize. * @since 0.10.0 */ public interface Serializer { - /** - * Converts the specified Java object into a formatted data byte array. - * - * @param t the object to serialize - * @return the serialized byte array representing the specified object. - * @throws SerializationException if there is a problem converting the object to a byte array. - * @deprecated since 0.12.0 in favor of {@link #serialize(Object, OutputStream)} - */ - @Deprecated byte[] serialize(T t) throws SerializationException; - /** - * Converts the specified Java object into a formatted data byte stream, writing the bytes to the specified - * {@code out}put stream. - * - * @param t the object to convert to a byte stream - * @param out the stream to write to - * @throws SerializationException if there is a problem converting the object to a byte stream or writing the - * bytes to the {@code out}put stream. - * @since 0.12.0 - */ - void serialize(T t, OutputStream out) throws SerializationException; } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonDeserializer.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonDeserializer.java (.../JacksonDeserializer.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonDeserializer.java (.../JacksonDeserializer.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,30 +18,26 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.ObjectMapper; + import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; -import io.jsonwebtoken.io.AbstractDeserializer; +import io.jsonwebtoken.io.DeserializationException; +import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.lang.Assert; import java.io.IOException; -import java.io.Reader; import java.util.Collections; import java.util.Map; /** - * Deserializer using a Jackson {@link ObjectMapper}. - * * @since 0.10.0 */ -public class JacksonDeserializer extends AbstractDeserializer { +public class JacksonDeserializer implements Deserializer { private final Class returnType; - private final ObjectMapper objectMapper; - /** - * Constructor using JJWT's default {@link ObjectMapper} singleton for deserialization. - */ + @SuppressWarnings("unused") //used via reflection by RuntimeClasspathDeserializerLocator public JacksonDeserializer() { this(JacksonSerializer.DEFAULT_OBJECT_MAPPER); } @@ -68,64 +64,25 @@ * If you would like to use your own {@code ObjectMapper} instance that also supports custom types for * JWT {@code Claims}, you will need to first customize your {@code ObjectMapper} instance by registering * your custom types and then use the {@link #JacksonDeserializer(ObjectMapper)} constructor instead. - * + * * @param claimTypeMap The claim name-to-class map used to deserialize claims into the given type */ - public JacksonDeserializer(Map> claimTypeMap) { - // DO NOT specify JacksonSerializer.DEFAULT_OBJECT_MAPPER here as that would modify the shared instance - this(JacksonSerializer.newObjectMapper(), claimTypeMap); - } - - /** - * Constructor using the specified Jackson {@link ObjectMapper}. - * - * @param objectMapper the ObjectMapper to use for deserialization. - */ - @SuppressWarnings("unchecked") - public JacksonDeserializer(ObjectMapper objectMapper) { - this(objectMapper, (Class) Object.class); - } - - /** - * Creates a new JacksonDeserializer where the values of the claims can be parsed into given types by registering - * a type-converting {@link com.fasterxml.jackson.databind.Module Module} on the specified {@link ObjectMapper}. - * A common usage example is to parse custom User object out of a claim, for example the claims: - *

    {@code
    -     * {
    -     *     "issuer": "https://issuer.example.com",
    -     *     "user": {
    -     *         "firstName": "Jill",
    -     *         "lastName": "Coder"
    -     *     }
    -     * }}
    - * Passing a map of {@code ["user": User.class]} to this constructor would result in the {@code user} claim being - * transformed to an instance of your custom {@code User} class, instead of the default of {@code Map}. - *

    - * Because custom type parsing requires modifying the state of a Jackson {@code ObjectMapper}, this - * constructor modifies the specified {@code objectMapper} argument and customizes it to support the - * specified {@code claimTypeMap}. - *

    - * If you do not want your {@code ObjectMapper} instance modified, but also want to support custom types for - * JWT {@code Claims}, you will need to first customize your {@code ObjectMapper} instance by registering - * your custom types separately and then use the {@link #JacksonDeserializer(ObjectMapper)} constructor instead - * (which does not modify the {@code objectMapper} argument). - * - * @param objectMapper the objectMapper to modify by registering a custom type-converting - * {@link com.fasterxml.jackson.databind.Module Module} - * @param claimTypeMap The claim name-to-class map used to deserialize claims into the given type - * @since 0.12.4 - */ - //TODO: Make this public on a minor release - // (cannot do that on a point release as that would violate semver) - private JacksonDeserializer(ObjectMapper objectMapper, Map> claimTypeMap) { - this(objectMapper); + public JacksonDeserializer(Map claimTypeMap) { + // DO NOT reuse JacksonSerializer.DEFAULT_OBJECT_MAPPER as this could result in sharing the custom deserializer + // between instances + this(new ObjectMapper()); Assert.notNull(claimTypeMap, "Claim type map cannot be null."); - // register a new Deserializer on the ObjectMapper instance: + // register a new Deserializer SimpleModule module = new SimpleModule(); module.addDeserializer(Object.class, new MappedTypeDeserializer(Collections.unmodifiableMap(claimTypeMap))); objectMapper.registerModule(module); } + @SuppressWarnings({"unchecked", "WeakerAccess", "unused"}) // for end-users providing a custom ObjectMapper + public JacksonDeserializer(ObjectMapper objectMapper) { + this(objectMapper, (Class) Object.class); + } + private JacksonDeserializer(ObjectMapper objectMapper, Class returnType) { Assert.notNull(objectMapper, "ObjectMapper cannot be null."); Assert.notNull(returnType, "Return type cannot be null."); @@ -134,19 +91,28 @@ } @Override - protected T doDeserialize(Reader reader) throws Exception { - return objectMapper.readValue(reader, returnType); + public T deserialize(byte[] bytes) throws DeserializationException { + try { + return readValue(bytes); + } catch (IOException e) { + String msg = "Unable to deserialize bytes into a " + returnType.getName() + " instance: " + e.getMessage(); + throw new DeserializationException(msg, e); + } } + protected T readValue(byte[] bytes) throws IOException { + return objectMapper.readValue(bytes, returnType); + } + /** * A Jackson {@link com.fasterxml.jackson.databind.JsonDeserializer JsonDeserializer}, that will convert claim * values to types based on {@code claimTypeMap}. */ private static class MappedTypeDeserializer extends UntypedObjectDeserializer { - private final Map> claimTypeMap; + private final Map claimTypeMap; - private MappedTypeDeserializer(Map> claimTypeMap) { + private MappedTypeDeserializer(Map claimTypeMap) { super(null, null); this.claimTypeMap = claimTypeMap; } @@ -156,8 +122,7 @@ // check if the current claim key is mapped, if so traverse it's value String name = parser.currentName(); if (claimTypeMap != null && name != null && claimTypeMap.containsKey(name)) { - Class type = claimTypeMap.get(name); - //noinspection resource + Class type = claimTypeMap.get(name); return parser.readValueAsTree().traverse(parser.getCodec()).readValueAs(type); } // otherwise default to super Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonSerializer.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonSerializer.java (.../JacksonSerializer.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonSerializer.java (.../JacksonSerializer.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,78 +15,45 @@ */ package io.jsonwebtoken.jackson.io; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.fasterxml.jackson.databind.module.SimpleModule; -import io.jsonwebtoken.io.AbstractSerializer; +import io.jsonwebtoken.io.SerializationException; +import io.jsonwebtoken.io.Serializer; import io.jsonwebtoken.lang.Assert; -import java.io.OutputStream; - /** - * Serializer using a Jackson {@link ObjectMapper}. - * * @since 0.10.0 */ -public class JacksonSerializer extends AbstractSerializer { +public class JacksonSerializer implements Serializer { - static final String MODULE_ID = "jjwt-jackson"; - static final Module MODULE; + static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper(); - static { - SimpleModule module = new SimpleModule(MODULE_ID); - module.addSerializer(JacksonSupplierSerializer.INSTANCE); - MODULE = module; - } + private final ObjectMapper objectMapper; - static final ObjectMapper DEFAULT_OBJECT_MAPPER = newObjectMapper(); - - /** - * Creates and returns a new ObjectMapper with the {@code jjwt-jackson} module registered and - * {@code JsonParser.Feature.STRICT_DUPLICATE_DETECTION} enabled (set to true) and - * {@code DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES} disabled (set to false). - * - * @return a new ObjectMapper with the {@code jjwt-jackson} module registered and - * {@code JsonParser.Feature.STRICT_DUPLICATE_DETECTION} enabled (set to true) and - * {@code DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES} disabled (set to false). - * - * @since 0.12.4 - */ - // package protected on purpose, do not expose to the public API - static ObjectMapper newObjectMapper() { - return new ObjectMapper() - .registerModule(MODULE) - .configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true) // https://github.com/jwtk/jjwt/issues/877 - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // https://github.com/jwtk/jjwt/issues/893 - } - - protected final ObjectMapper objectMapper; - - /** - * Constructor using JJWT's default {@link ObjectMapper} singleton for serialization. - */ + @SuppressWarnings("unused") //used via reflection by RuntimeClasspathDeserializerLocator public JacksonSerializer() { this(DEFAULT_OBJECT_MAPPER); } - /** - * Creates a new Jackson Serializer that uses the specified {@link ObjectMapper} for serialization. - * - * @param objectMapper the ObjectMapper to use for serialization. - */ + @SuppressWarnings("WeakerAccess") //intended for end-users to use when providing a custom ObjectMapper public JacksonSerializer(ObjectMapper objectMapper) { Assert.notNull(objectMapper, "ObjectMapper cannot be null."); - this.objectMapper = objectMapper.registerModule(MODULE); + this.objectMapper = objectMapper; } @Override - protected void doSerialize(T t, OutputStream out) throws Exception { - Assert.notNull(out, "OutputStream cannot be null."); - ObjectWriter writer = this.objectMapper.writer().without(JsonGenerator.Feature.AUTO_CLOSE_TARGET); - writer.writeValue(out, t); + public byte[] serialize(T t) throws SerializationException { + Assert.notNull(t, "Object to serialize cannot be null."); + try { + return writeValueAsBytes(t); + } catch (JsonProcessingException e) { + String msg = "Unable to serialize object: " + e.getMessage(); + throw new SerializationException(msg, e); + } } + + @SuppressWarnings("WeakerAccess") //for testing + protected byte[] writeValueAsBytes(T t) throws JsonProcessingException { + return this.objectMapper.writeValueAsBytes(t); + } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/jackson/io/JacksonSupplierSerializer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Arrays.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Arrays.java (.../Arrays.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Arrays.java (.../Arrays.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,105 +15,18 @@ */ package io.jsonwebtoken.lang; -import java.lang.reflect.Array; -import java.util.List; - /** - * Utility methods to work with array instances. - * * @since 0.6 */ public final class Arrays { - private Arrays() { - } //prevent instantiation + private Arrays(){} //prevent instantiation - /** - * Returns the length of the array, or {@code 0} if the array is {@code null}. - * - * @param a the possibly-null array - * @param the type of elements in the array - * @return the length of the array, or zero if the array is null. - */ - public static int length(T[] a) { - return a == null ? 0 : a.length; - } - - /** - * Converts the specified array to a {@link List}. If the array is empty, an empty list will be returned. - * - * @param a the array to represent as a list - * @param the type of elements in the array - * @return the array as a list, or an empty list if the array is empty. - */ - public static List asList(T[] a) { - return Objects.isEmpty(a) ? Collections.emptyList() : java.util.Arrays.asList(a); - } - - /** - * Returns the length of the specified byte array, or {@code 0} if the byte array is {@code null}. - * - * @param bytes the array to check - * @return the length of the specified byte array, or {@code 0} if the byte array is {@code null}. - */ public static int length(byte[] bytes) { return bytes != null ? bytes.length : 0; } - /** - * Returns the byte array unaltered if it is non-null and has a positive length, otherwise {@code null}. - * - * @param bytes the byte array to check. - * @return the byte array unaltered if it is non-null and has a positive length, otherwise {@code null}. - */ public static byte[] clean(byte[] bytes) { return length(bytes) > 0 ? bytes : null; } - - /** - * Creates a shallow copy of the specified object or array. - * - * @param obj the object to copy - * @return a shallow copy of the specified object or array. - */ - public static Object copy(Object obj) { - if (obj == null) { - return null; - } - Assert.isTrue(Objects.isArray(obj), "Argument must be an array."); - if (obj instanceof Object[]) { - return ((Object[]) obj).clone(); - } - if (obj instanceof boolean[]) { - return ((boolean[]) obj).clone(); - } - if (obj instanceof byte[]) { - return ((byte[]) obj).clone(); - } - if (obj instanceof char[]) { - return ((char[]) obj).clone(); - } - if (obj instanceof double[]) { - return ((double[]) obj).clone(); - } - if (obj instanceof float[]) { - return ((float[]) obj).clone(); - } - if (obj instanceof int[]) { - return ((int[]) obj).clone(); - } - if (obj instanceof long[]) { - return ((long[]) obj).clone(); - } - if (obj instanceof short[]) { - return ((short[]) obj).clone(); - } - Class componentType = obj.getClass().getComponentType(); - int length = Array.getLength(obj); - Object[] copy = (Object[]) Array.newInstance(componentType, length); - for (int i = 0; i < length; i++) { - copy[i] = Array.get(obj, i); - } - return copy; - } } Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Assert.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Assert.java (.../Assert.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Assert.java (.../Assert.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,22 +18,16 @@ import java.util.Collection; import java.util.Map; -/** - * Utility methods for providing argument and state assertions to reduce repeating these patterns and otherwise - * increasing cyclomatic complexity. - */ public final class Assert { - private Assert() { - } //prevent instantiation + private Assert(){} //prevent instantiation /** * Assert a boolean expression, throwing IllegalArgumentException * if the test result is false. *

    Assert.isTrue(i > 0, "The value must be greater than zero");
    - * * @param expression a boolean expression - * @param message the exception message to use if the assertion fails + * @param message the exception message to use if the assertion fails * @throws IllegalArgumentException if expression is false */ public static void isTrue(boolean expression, String message) { @@ -46,7 +40,6 @@ * Assert a boolean expression, throwing IllegalArgumentException * if the test result is false. *
    Assert.isTrue(i > 0);
    - * * @param expression a boolean expression * @throws IllegalArgumentException if expression is false */ @@ -57,8 +50,7 @@ /** * Assert that an object is null . *
    Assert.isNull(value, "The value must be null");
    - * - * @param object the object to check + * @param object the object to check * @param message the exception message to use if the assertion fails * @throws IllegalArgumentException if the object is not null */ @@ -71,7 +63,6 @@ /** * Assert that an object is null . *
    Assert.isNull(value);
    - * * @param object the object to check * @throws IllegalArgumentException if the object is not null */ @@ -82,24 +73,19 @@ /** * Assert that an object is not null . *
    Assert.notNull(clazz, "The class must not be null");
    - * - * @param object the object to check - * @param the type of object + * @param object the object to check * @param message the exception message to use if the assertion fails - * @return the non-null object * @throws IllegalArgumentException if the object is null */ - public static T notNull(T object, String message) { + public static void notNull(Object object, String message) { if (object == null) { throw new IllegalArgumentException(message); } - return object; } /** * Assert that an object is not null . *
    Assert.notNull(clazz);
    - * * @param object the object to check * @throws IllegalArgumentException if the object is null */ @@ -111,8 +97,7 @@ * Assert that the given String is not empty; that is, * it must not be null and not the empty String. *
    Assert.hasLength(name, "Name must not be empty");
    - * - * @param text the String to check + * @param text the String to check * @param message the exception message to use if the assertion fails * @see Strings#hasLength */ @@ -126,38 +111,32 @@ * Assert that the given String is not empty; that is, * it must not be null and not the empty String. *
    Assert.hasLength(name);
    - * * @param text the String to check * @see Strings#hasLength */ public static void hasLength(String text) { hasLength(text, - "[Assertion failed] - this String argument must have length; it must not be null or empty"); + "[Assertion failed] - this String argument must have length; it must not be null or empty"); } /** * Assert that the given String has valid text content; that is, it must not * be null and must contain at least one non-whitespace character. *
    Assert.hasText(name, "'name' must not be empty");
    - * - * @param the type of CharSequence - * @param text the CharSequence to check + * @param text the String to check * @param message the exception message to use if the assertion fails - * @return the CharSequence if it has text * @see Strings#hasText */ - public static T hasText(T text, String message) { + public static void hasText(String text, String message) { if (!Strings.hasText(text)) { throw new IllegalArgumentException(message); } - return text; } /** * Assert that the given String has valid text content; that is, it must not * be null and must contain at least one non-whitespace character. *
    Assert.hasText(name, "'name' must not be empty");
    - * * @param text the String to check * @see Strings#hasText */ @@ -169,98 +148,65 @@ /** * Assert that the given text does not contain the given substring. *
    Assert.doesNotContain(name, "rod", "Name must not contain 'rod'");
    - * * @param textToSearch the text to search - * @param substring the substring to find within the text - * @param message the exception message to use if the assertion fails + * @param substring the substring to find within the text + * @param message the exception message to use if the assertion fails */ public static void doesNotContain(String textToSearch, String substring, String message) { if (Strings.hasLength(textToSearch) && Strings.hasLength(substring) && - textToSearch.indexOf(substring) != -1) { + textToSearch.indexOf(substring) != -1) { throw new IllegalArgumentException(message); } } /** * Assert that the given text does not contain the given substring. *
    Assert.doesNotContain(name, "rod");
    - * * @param textToSearch the text to search - * @param substring the substring to find within the text + * @param substring the substring to find within the text */ public static void doesNotContain(String textToSearch, String substring) { doesNotContain(textToSearch, substring, - "[Assertion failed] - this String argument must not contain the substring [" + substring + "]"); + "[Assertion failed] - this String argument must not contain the substring [" + substring + "]"); } /** * Assert that an array has elements; that is, it must not be * null and must have at least one element. *
    Assert.notEmpty(array, "The array must have elements");
    - * - * @param array the array to check + * @param array the array to check * @param message the exception message to use if the assertion fails - * @return the non-empty array for immediate use * @throws IllegalArgumentException if the object array is null or has no elements */ - public static Object[] notEmpty(Object[] array, String message) { + public static void notEmpty(Object[] array, String message) { if (Objects.isEmpty(array)) { throw new IllegalArgumentException(message); } - return array; } /** * Assert that an array has elements; that is, it must not be * null and must have at least one element. *
    Assert.notEmpty(array);
    - * * @param array the array to check * @throws IllegalArgumentException if the object array is null or has no elements */ public static void notEmpty(Object[] array) { notEmpty(array, "[Assertion failed] - this array must not be empty: it must contain at least 1 element"); } - /** - * Assert that the specified byte array is not null and has at least one byte element. - * - * @param array the byte array to check - * @param msg the exception message to use if the assertion fails - * @return the byte array if the assertion passes - * @throws IllegalArgumentException if the byte array is null or empty - * @since 0.12.0 - */ - public static byte[] notEmpty(byte[] array, String msg) { + public static void notEmpty(byte[] array, String msg) { if (Objects.isEmpty(array)) { throw new IllegalArgumentException(msg); } - return array; } /** - * Assert that the specified character array is not null and has at least one byte element. - * - * @param chars the character array to check - * @param msg the exception message to use if the assertion fails - * @return the character array if the assertion passes - * @throws IllegalArgumentException if the character array is null or empty - * @since 0.12.0 - */ - public static char[] notEmpty(char[] chars, String msg) { - if (Objects.isEmpty(chars)) { - throw new IllegalArgumentException(msg); - } - return chars; - } - - /** * Assert that an array has no null elements. * Note: Does not complain if the array is empty! *
    Assert.noNullElements(array, "The array must have non-null elements");
    - * - * @param array the array to check + * @param array the array to check * @param message the exception message to use if the assertion fails * @throws IllegalArgumentException if the object array contains a null element */ @@ -278,7 +224,6 @@ * Assert that an array has no null elements. * Note: Does not complain if the array is empty! *
    Assert.noNullElements(array);
    - * * @param array the array to check * @throws IllegalArgumentException if the object array contains a null element */ @@ -290,56 +235,46 @@ * Assert that a collection has elements; that is, it must not be * null and must have at least one element. *
    Assert.notEmpty(collection, "Collection must have elements");
    - * * @param collection the collection to check - * @param the type of collection - * @param message the exception message to use if the assertion fails - * @return the non-null, non-empty collection + * @param message the exception message to use if the assertion fails * @throws IllegalArgumentException if the collection is null or has no elements */ - public static > T notEmpty(T collection, String message) { + public static void notEmpty(Collection collection, String message) { if (Collections.isEmpty(collection)) { throw new IllegalArgumentException(message); } - return collection; } /** * Assert that a collection has elements; that is, it must not be * null and must have at least one element. *
    Assert.notEmpty(collection, "Collection must have elements");
    - * * @param collection the collection to check * @throws IllegalArgumentException if the collection is null or has no elements */ - public static void notEmpty(Collection collection) { + public static void notEmpty(Collection collection) { notEmpty(collection, - "[Assertion failed] - this collection must not be empty: it must contain at least 1 element"); + "[Assertion failed] - this collection must not be empty: it must contain at least 1 element"); } /** * Assert that a Map has entries; that is, it must not be null * and must have at least one entry. *
    Assert.notEmpty(map, "Map must have entries");
    - * - * @param map the map to check - * @param the type of Map to check + * @param map the map to check * @param message the exception message to use if the assertion fails - * @return the non-null, non-empty map * @throws IllegalArgumentException if the map is null or has no entries */ - public static > T notEmpty(T map, String message) { + public static void notEmpty(Map map, String message) { if (Collections.isEmpty(map)) { throw new IllegalArgumentException(message); } - return map; } /** * Assert that a Map has entries; that is, it must not be null * and must have at least one entry. *
    Assert.notEmpty(map);
    - * * @param map the map to check * @throws IllegalArgumentException if the map is null or has no entries */ @@ -351,75 +286,41 @@ /** * Assert that the provided object is an instance of the provided class. *
    Assert.instanceOf(Foo.class, foo);
    - * - * @param the type of instance expected * @param clazz the required class - * @param obj the object to check - * @return the expected instance of type {@code T} + * @param obj the object to check * @throws IllegalArgumentException if the object is not an instance of clazz * @see Class#isInstance */ - public static T isInstanceOf(Class clazz, Object obj) { - return isInstanceOf(clazz, obj, ""); + public static void isInstanceOf(Class clazz, Object obj) { + isInstanceOf(clazz, obj, ""); } /** * Assert that the provided object is an instance of the provided class. *
    Assert.instanceOf(Foo.class, foo);
    - * - * @param type the type to check against - * @param the object's expected type - * @param obj the object to check + * @param type the type to check against + * @param obj the object to check * @param message a message which will be prepended to the message produced by - * the function itself, and which may be used to provide context. It should - * normally end in a ": " or ". " so that the function generate message looks - * ok when prepended to it. - * @return the non-null object IFF it is an instance of the specified {@code type}. + * the function itself, and which may be used to provide context. It should + * normally end in a ": " or ". " so that the function generate message looks + * ok when prepended to it. * @throws IllegalArgumentException if the object is not an instance of clazz * @see Class#isInstance */ - public static T isInstanceOf(Class type, Object obj, String message) { + public static void isInstanceOf(Class type, Object obj, String message) { notNull(type, "Type to check against must not be null"); if (!type.isInstance(obj)) { throw new IllegalArgumentException(message + - "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + - "] must be an instance of " + type); + "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + + "] must be an instance of " + type); } - return type.cast(obj); } /** - * Asserts that the provided object is an instance of the provided class, throwing an - * {@link IllegalStateException} otherwise. - *
    Assert.stateIsInstance(Foo.class, foo);
    - * - * @param type the type to check against - * @param the object's expected type - * @param obj the object to check - * @param message a message which will be prepended to the message produced by - * the function itself, and which may be used to provide context. It should - * normally end in a ": " or ". " so that the function generate message looks - * ok when prepended to it. - * @return the non-null object IFF it is an instance of the specified {@code type}. - * @throws IllegalStateException if the object is not an instance of clazz - * @see Class#isInstance - */ - public static T stateIsInstance(Class type, Object obj, String message) { - notNull(type, "Type to check cannot be null."); - if (!type.isInstance(obj)) { - String msg = message + "Object of class [" + Objects.nullSafeClassName(obj) + - "] must be an instance of " + type; - throw new IllegalStateException(msg); - } - return type.cast(obj); - } - - /** * Assert that superType.isAssignableFrom(subType) is true. *
    Assert.isAssignable(Number.class, myClass);
    - * * @param superType the super type to check - * @param subType the sub type to check + * @param subType the sub type to check * @throws IllegalArgumentException if the classes are not assignable */ public static void isAssignable(Class superType, Class subType) { @@ -429,13 +330,12 @@ /** * Assert that superType.isAssignableFrom(subType) is true. *
    Assert.isAssignable(Number.class, myClass);
    - * * @param superType the super type to check against - * @param subType the sub type to check - * @param message a message which will be prepended to the message produced by - * the function itself, and which may be used to provide context. It should - * normally end in a ": " or ". " so that the function generate message looks - * ok when prepended to it. + * @param subType the sub type to check + * @param message a message which will be prepended to the message produced by + * the function itself, and which may be used to provide context. It should + * normally end in a ": " or ". " so that the function generate message looks + * ok when prepended to it. * @throws IllegalArgumentException if the classes are not assignable */ public static void isAssignable(Class superType, Class subType, String message) { @@ -445,75 +345,14 @@ } } - /** - * Asserts that a specified {@code value} is equal to the given {@code requirement}, throwing - * an {@link IllegalArgumentException} with the given message if not. - * - * @param the type of argument - * @param value the value to check - * @param requirement the requirement that {@code value} must be greater than - * @param msg the message to use for the {@code IllegalArgumentException} if thrown. - * @return {@code value} if greater than the specified {@code requirement}. - * @since 0.12.0 - */ - public static > T eq(T value, T requirement, String msg) { - if (compareTo(value, requirement) != 0) { - throw new IllegalArgumentException(msg); - } - return value; - } - private static > int compareTo(T value, T requirement) { - notNull(value, "value cannot be null."); - notNull(requirement, "requirement cannot be null."); - return value.compareTo(requirement); - } - /** - * Asserts that a specified {@code value} is greater than the given {@code requirement}, throwing - * an {@link IllegalArgumentException} with the given message if not. - * - * @param the type of value to check and return if the requirement is met - * @param value the value to check - * @param requirement the requirement that {@code value} must be greater than - * @param msg the message to use for the {@code IllegalArgumentException} if thrown. - * @return {@code value} if greater than the specified {@code requirement}. - * @since 0.12.0 - */ - public static > T gt(T value, T requirement, String msg) { - if (!(compareTo(value, requirement) > 0)) { - throw new IllegalArgumentException(msg); - } - return value; - } - - /** - * Asserts that a specified {@code value} is less than or equal to the given {@code requirement}, throwing - * an {@link IllegalArgumentException} with the given message if not. - * - * @param the type of value to check and return if the requirement is met - * @param value the value to check - * @param requirement the requirement that {@code value} must be greater than - * @param msg the message to use for the {@code IllegalArgumentException} if thrown. - * @return {@code value} if greater than the specified {@code requirement}. - * @since 0.12.0 - */ - public static > T lte(T value, T requirement, String msg) { - if (compareTo(value, requirement) > 0) { - throw new IllegalArgumentException(msg); - } - return value; - } - - - /** * Assert a boolean expression, throwing IllegalStateException * if the test result is false. Call isTrue if you wish to * throw IllegalArgumentException on an assertion failure. *
    Assert.state(id == null, "The id property must not already be initialized");
    - * * @param expression a boolean expression - * @param message the exception message to use if the assertion fails + * @param message the exception message to use if the assertion fails * @throws IllegalStateException if expression is false */ public static void state(boolean expression, String message) { @@ -528,31 +367,11 @@ *

    Call {@link #isTrue(boolean)} if you wish to * throw {@link IllegalArgumentException} on an assertion failure. *

    Assert.state(id == null);
    - * * @param expression a boolean expression * @throws IllegalStateException if the supplied expression is false */ public static void state(boolean expression) { state(expression, "[Assertion failed] - this state invariant must be true"); } - /** - * Asserts that the specified {@code value} is not null, otherwise throws an - * {@link IllegalStateException} with the specified {@code msg}. Intended to be used with - * code invariants (as opposed to method arguments, like {@link #notNull(Object)}). - * - * @param value value to assert is not null - * @param msg exception message to use if {@code value} is null - * @param value type - * @return the non-null value - * @throws IllegalStateException with the specified {@code msg} if {@code value} is null. - * @since 0.12.0 - */ - public static T stateNotNull(T value, String msg) throws IllegalStateException { - if (value == null) { - throw new IllegalStateException(msg); - } - return value; - } - } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Builder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Classes.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Classes.java (.../Classes.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Classes.java (.../Classes.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -17,38 +17,41 @@ import java.io.InputStream; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URL; /** - * Utility methods for working with {@link Class}es. - * * @since 0.1 */ public final class Classes { - private Classes() { - } //prevent instantiation + private Classes() {} //prevent instantiation + /** + * @since 0.1 + */ private static final ClassLoaderAccessor THREAD_CL_ACCESSOR = new ExceptionIgnoringAccessor() { @Override - protected ClassLoader doGetClassLoader() { + protected ClassLoader doGetClassLoader() throws Throwable { return Thread.currentThread().getContextClassLoader(); } }; + /** + * @since 0.1 + */ private static final ClassLoaderAccessor CLASS_CL_ACCESSOR = new ExceptionIgnoringAccessor() { @Override - protected ClassLoader doGetClassLoader() { + protected ClassLoader doGetClassLoader() throws Throwable { return Classes.class.getClassLoader(); } }; + /** + * @since 0.1 + */ private static final ClassLoaderAccessor SYSTEM_CL_ACCESSOR = new ExceptionIgnoringAccessor() { @Override - protected ClassLoader doGetClassLoader() { + protected ClassLoader doGetClassLoader() throws Throwable { return ClassLoader.getSystemClassLoader(); } }; @@ -62,14 +65,13 @@ * the JRE's ClassNotFoundException. * * @param fqcn the fully qualified class name to load - * @param The type of Class returned * @return the located class * @throws UnknownClassException if the class cannot be found. */ @SuppressWarnings("unchecked") public static Class forName(String fqcn) throws UnknownClassException { - Class clazz = THREAD_CL_ACCESSOR.loadClass(fqcn); + Class clazz = THREAD_CL_ACCESSOR.loadClass(fqcn); if (clazz == null) { clazz = CLASS_CL_ACCESSOR.loadClass(fqcn); @@ -90,7 +92,7 @@ throw new UnknownClassException(msg); } - return (Class) clazz; + return clazz; } /** @@ -120,37 +122,6 @@ return is; } - /** - * Returns the specified resource URL by checking the current thread's - * {@link Thread#getContextClassLoader() context class loader}, then the - * current ClassLoader (Classes.class.getClassLoader()), then the system/application - * ClassLoader (ClassLoader.getSystemClassLoader(), in that order, using - * {@link ClassLoader#getResource(String) getResource(name)}. - * - * @param name the name of the resource to acquire from the classloader(s). - * @return the URL of the resource found, or null if the resource cannot be found from any - * of the three mentioned ClassLoaders. - * @since 0.12.0 - */ - private static URL getResource(String name) { - URL url = THREAD_CL_ACCESSOR.getResource(name); - if (url == null) { - url = CLASS_CL_ACCESSOR.getResource(name); - } - if (url == null) { - return SYSTEM_CL_ACCESSOR.getResource(name); - } - return url; - } - - /** - * Returns {@code true} if the specified {@code fullyQualifiedClassName} can be found in any of the thread - * context, class, or system classloaders, or {@code false} otherwise. - * - * @param fullyQualifiedClassName the fully qualified class name to check - * @return {@code true} if the specified {@code fullyQualifiedClassName} can be found in any of the thread - * context, class, or system classloaders, or {@code false} otherwise. - */ public static boolean isAvailable(String fullyQualifiedClassName) { try { forName(fullyQualifiedClassName); @@ -160,56 +131,22 @@ } } - /** - * Creates and returns a new instance of the class with the specified fully qualified class name using the - * classes default no-argument constructor. - * - * @param fqcn the fully qualified class name - * @param the type of object created - * @return a new instance of the specified class name - */ @SuppressWarnings("unchecked") public static T newInstance(String fqcn) { - return (T) newInstance(forName(fqcn)); + return (T)newInstance(forName(fqcn)); } - /** - * Creates and returns a new instance of the specified fully qualified class name using the - * specified {@code args} arguments provided to the constructor with {@code ctorArgTypes} - * - * @param fqcn the fully qualified class name - * @param ctorArgTypes the argument types of the constructor to invoke - * @param args the arguments to supply when invoking the constructor - * @param the type of object created - * @return the newly created object - */ - public static T newInstance(String fqcn, Class[] ctorArgTypes, Object... args) { + public static T newInstance(String fqcn, Class[] ctorArgTypes, Object... args) { Class clazz = forName(fqcn); Constructor ctor = getConstructor(clazz, ctorArgTypes); return instantiate(ctor, args); } - /** - * Creates and returns a new instance of the specified fully qualified class name using a constructor that matches - * the specified {@code args} arguments. - * - * @param fqcn fully qualified class name - * @param args the arguments to supply to the constructor - * @param the type of the object created - * @return the newly created object - */ @SuppressWarnings("unchecked") public static T newInstance(String fqcn, Object... args) { - return (T) newInstance(forName(fqcn), args); + return (T)newInstance(forName(fqcn), args); } - /** - * Creates a new instance of the specified {@code clazz} via {@code clazz.newInstance()}. - * - * @param clazz the class to invoke - * @param the type of the object created - * @return the newly created object - */ public static T newInstance(Class clazz) { if (clazz == null) { String msg = "Class method parameter cannot be null."; @@ -222,35 +159,16 @@ } } - /** - * Returns a new instance of the specified {@code clazz}, invoking the associated constructor with the specified - * {@code args} arguments. - * - * @param clazz the class to invoke - * @param args the arguments matching an associated class constructor - * @param the type of the created object - * @return the newly created object - */ public static T newInstance(Class clazz, Object... args) { - Class[] argTypes = new Class[args.length]; + Class[] argTypes = new Class[args.length]; for (int i = 0; i < args.length; i++) { argTypes[i] = args[i].getClass(); } Constructor ctor = getConstructor(clazz, argTypes); return instantiate(ctor, args); } - /** - * Returns the {@link Constructor} for the specified {@code Class} with arguments matching the specified - * {@code argTypes}. - * - * @param clazz the class to inspect - * @param argTypes the argument types for the desired constructor - * @param the type of object to create - * @return the constructor matching the specified argument types - * @throws IllegalStateException if the constructor for the specified {@code argTypes} does not exist. - */ - public static Constructor getConstructor(Class clazz, Class... argTypes) throws IllegalStateException { + public static Constructor getConstructor(Class clazz, Class... argTypes) { try { return clazz.getConstructor(argTypes); } catch (NoSuchMethodException e) { @@ -259,16 +177,6 @@ } - /** - * Creates a new object using the specified {@link Constructor}, invoking it with the specified constructor - * {@code args} arguments. - * - * @param ctor the constructor to invoke - * @param args the arguments to supply to the constructor - * @param the type of object to create - * @return the new object instance - * @throws InstantiationException if the constructor cannot be invoked successfully - */ public static T instantiate(Constructor ctor, Object... args) { try { return ctor.newInstance(args); @@ -279,88 +187,28 @@ } /** - * Invokes the fully qualified class name's method named {@code methodName} with parameters of type {@code argTypes} - * using the {@code args} as the method arguments. - * - * @param fqcn fully qualified class name to locate - * @param methodName name of the method to invoke on the class - * @param argTypes the method argument types supported by the {@code methodName} method - * @param args the runtime arguments to use when invoking the located class method - * @param the expected type of the object returned from the invoked method. - * @return the result returned by the invoked method * @since 0.10.0 */ - public static T invokeStatic(String fqcn, String methodName, Class[] argTypes, Object... args) { - try { - Class clazz = Classes.forName(fqcn); - return invokeStatic(clazz, methodName, argTypes, args); - } catch (Exception e) { - String msg = "Unable to invoke class method " + fqcn + "#" + methodName + ". Ensure the necessary " + - "implementation is in the runtime classpath."; - throw new IllegalStateException(msg, e); - } - } - - /** - * Invokes the {@code clazz}'s matching static method (named {@code methodName} with exact argument types - * of {@code argTypes}) with the given {@code args} arguments, and returns the method return value. - * - * @param clazz the class to invoke - * @param methodName the name of the static method on {@code clazz} to invoke - * @param argTypes the types of the arguments accepted by the method - * @param args the actual runtime arguments to use when invoking the method - * @param the type of object expected to be returned from the method - * @return the result returned by the invoked method. - * @since 0.12.0 - */ @SuppressWarnings("unchecked") - public static T invokeStatic(Class clazz, String methodName, Class[] argTypes, Object... args) { + public static T invokeStatic(String fqcn, String methodName, Class[] argTypes, Object... args) { try { + Class clazz = Classes.forName(fqcn); Method method = clazz.getDeclaredMethod(methodName, argTypes); method.setAccessible(true); - return (T) method.invoke(null, args); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) { - throw ((RuntimeException) cause); //propagate - } - String msg = "Unable to invoke class method " + clazz.getName() + "#" + methodName + - ". Ensure the necessary implementation is in the runtime classpath."; + return(T)method.invoke(null, args); + } catch (Exception e) { + String msg = "Unable to invoke class method " + fqcn + "#" + methodName + ". Ensure the necessary " + + "implementation is in the runtime classpath."; throw new IllegalStateException(msg, e); } } /** - * Returns the {@code instance}'s named (declared) field value. - * - * @param instance the instance with the internal field - * @param fieldName the name of the field to inspect - * @param fieldType the type of field to inspect - * @param field instance value type - * @return the field value - */ - public static T getFieldValue(Object instance, String fieldName, Class fieldType) { - if (instance == null) return null; - try { - Field field = instance.getClass().getDeclaredField(fieldName); - field.setAccessible(true); - Object o = field.get(instance); - return fieldType.cast(o); - } catch (Throwable t) { - String msg = "Unable to read field " + instance.getClass().getName() + - "#" + fieldName + ": " + t.getMessage(); - throw new IllegalStateException(msg, t); - } - } - - /** * @since 1.0 */ - private interface ClassLoaderAccessor { - Class loadClass(String fqcn); + private static interface ClassLoaderAccessor { + Class loadClass(String fqcn); - URL getResource(String name); - InputStream getResourceStream(String name); } @@ -369,8 +217,8 @@ */ private static abstract class ExceptionIgnoringAccessor implements ClassLoaderAccessor { - public Class loadClass(String fqcn) { - Class clazz = null; + public Class loadClass(String fqcn) { + Class clazz = null; ClassLoader cl = getClassLoader(); if (cl != null) { try { @@ -382,16 +230,6 @@ return clazz; } - @Override - public URL getResource(String name) { - URL url = null; - ClassLoader cl = getClassLoader(); - if (cl != null) { - url = cl.getResource(name); - } - return url; - } - public InputStream getResourceStream(String name) { InputStream is = null; ClassLoader cl = getClassLoader(); Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/CollectionMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Collections.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Collections.java (.../Collections.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Collections.java (.../Collections.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -20,197 +20,22 @@ import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; -/** - * Utility methods for working with {@link Collection}s, {@link List}s, {@link Set}s, and {@link Maps}. - */ -@SuppressWarnings({"unused", "rawtypes"}) public final class Collections { - private Collections() { - } //prevent instantiation + private Collections(){} //prevent instantiation /** - * Returns a type-safe immutable empty {@code List}. - * - * @param list element type - * @return a type-safe immutable empty {@code List}. - */ - public static List emptyList() { - return java.util.Collections.emptyList(); - } - - /** - * Returns a type-safe immutable empty {@code Set}. - * - * @param set element type - * @return a type-safe immutable empty {@code Set}. - */ - @SuppressWarnings("unused") - public static Set emptySet() { - return java.util.Collections.emptySet(); - } - - /** - * Returns a type-safe immutable empty {@code Map}. - * - * @param map key type - * @param map value type - * @return a type-safe immutable empty {@code Map}. - */ - @SuppressWarnings("unused") - public static Map emptyMap() { - return java.util.Collections.emptyMap(); - } - - /** - * Returns a type-safe immutable {@code List} containing the specified array elements. - * - * @param elements array elements to include in the list - * @param list element type - * @return a type-safe immutable {@code List} containing the specified array elements. - */ - @SafeVarargs - public static List of(T... elements) { - if (elements == null || elements.length == 0) { - return java.util.Collections.emptyList(); - } - return java.util.Collections.unmodifiableList(Arrays.asList(elements)); - } - - /** - * Returns the specified collection as a {@link Set} instance. - * - * @param c the collection to represent as a set - * @param collection element type - * @return a type-safe immutable {@code Set} containing the specified collection elements. - * @since 0.12.0 - */ - public static Set asSet(Collection c) { - if (c instanceof Set) { - return (Set) c; - } - if (isEmpty(c)) { - return java.util.Collections.emptySet(); - } - return java.util.Collections.unmodifiableSet(new LinkedHashSet<>(c)); - } - - /** - * Returns a type-safe immutable {@code Set} containing the specified array elements. - * - * @param elements array elements to include in the set - * @param set element type - * @return a type-safe immutable {@code Set} containing the specified array elements. - */ - @SafeVarargs - public static Set setOf(T... elements) { - if (elements == null || elements.length == 0) { - return java.util.Collections.emptySet(); - } - Set set = new LinkedHashSet<>(Arrays.asList(elements)); - return immutable(set); - } - - /** - * Shorter null-safe convenience alias for {@link java.util.Collections#unmodifiableList(List)} so both classes - * don't need to be imported. - * - * @param m map to wrap in an immutable/unmodifiable collection - * @param map key type - * @param map value type - * @return an immutable wrapper for {@code m}. - * @since 0.12.0 - */ - public static Map immutable(Map m) { - return m != null ? java.util.Collections.unmodifiableMap(m) : null; - } - - /** - * Shorter null-safe convenience alias for {@link java.util.Collections#unmodifiableSet(Set)} so both classes don't - * need to be imported. - * - * @param set set to wrap in an immutable Set - * @param set element type - * @return an immutable wrapper for {@code set} - */ - public static Set immutable(Set set) { - return set != null ? java.util.Collections.unmodifiableSet(set) : null; - } - - /** - * Shorter null-safe convenience alias for {@link java.util.Collections#unmodifiableList(List)} so both classes - * don't need to be imported. - * - * @param list list to wrap in an immutable List - * @param list element type - * @return an immutable wrapper for {@code list} - */ - public static List immutable(List list) { - return list != null ? java.util.Collections.unmodifiableList(list) : null; - } - - /** - * Null-safe factory method that returns an immutable/unmodifiable view of the specified collection instance. - * Works for {@link List}, {@link Set} and {@link Collection} arguments. - * - * @param c collection to wrap in an immutable/unmodifiable collection - * @param type of collection - * @param type of elements in the collection - * @return an immutable wrapper for {@code l}. - * @since 0.12.0 - */ - @SuppressWarnings("unchecked") - public static > C immutable(C c) { - if (c == null) { - return null; - } else if (c instanceof Set) { - return (C) java.util.Collections.unmodifiableSet((Set) c); - } else if (c instanceof List) { - return (C) java.util.Collections.unmodifiableList((List) c); - } else { - return (C) java.util.Collections.unmodifiableCollection(c); - } - } - - /** - * Returns a non-null set, either {@code s} if it is not null, or {@link #emptySet()} otherwise. - * - * @param s the set to check for null - * @param type of elements in the set - * @return a non-null set, either {@code s} if it is not null, or {@link #emptySet()} otherwise. - * @since 0.12.0 - */ - public static Set nullSafe(Set s) { - return s == null ? Collections.emptySet() : s; - } - - /** - * Returns a non-null collection, either {@code c} if it is not null, or {@link #emptyList()} otherwise. - * - * @param c the collection to check for null - * @param type of elements in the collection - * @return a non-null collection, either {@code c} if it is not null, or {@link #emptyList()} otherwise. - * @since 0.12.0 - */ - public static Collection nullSafe(Collection c) { - return c == null ? Collections.emptyList() : c; - } - - /** * Return true if the supplied Collection is null * or empty. Otherwise, return false. - * * @param collection the Collection to check * @return whether the given Collection is empty */ - public static boolean isEmpty(Collection collection) { - return size(collection) == 0; + public static boolean isEmpty(Collection collection) { + return (collection == null || collection.isEmpty()); } /** @@ -220,7 +45,7 @@ * @return the collection's size or {@code 0} if the collection is {@code null}. * @since 0.9.2 */ - public static int size(Collection collection) { + public static int size(Collection collection) { return collection == null ? 0 : collection.size(); } @@ -231,27 +56,25 @@ * @return the map's size or {@code 0} if the map is {@code null}. * @since 0.9.2 */ - public static int size(Map map) { + public static int size(Map map) { return map == null ? 0 : map.size(); } /** * Return true if the supplied Map is null * or empty. Otherwise, return false. - * * @param map the Map to check * @return whether the given Map is empty */ - public static boolean isEmpty(Map map) { - return size(map) == 0; + public static boolean isEmpty(Map map) { + return (map == null || map.isEmpty()); } /** * Convert the supplied array into a List. A primitive array gets * converted into a List of the appropriate wrapper type. *

    A null source value will be converted to an * empty List. - * * @param source the (potentially primitive) array * @return the converted List result * @see Objects#toObjectArray(Object) @@ -261,27 +84,8 @@ } /** - * Concatenate the specified set with the specified array elements, resulting in a new {@link LinkedHashSet} with - * the array elements appended to the end of the existing Set. - * - * @param c the set to append to - * @param elements the array elements to append to the end of the set - * @param set element type - * @return a new {@link LinkedHashSet} with the array elements appended to the end of the original set. - */ - @SafeVarargs - public static Set concat(Set c, T... elements) { - int size = Math.max(1, Collections.size(c) + io.jsonwebtoken.lang.Arrays.length(elements)); - Set set = new LinkedHashSet<>(size); - set.addAll(c); - java.util.Collections.addAll(set, elements); - return immutable(set); - } - - /** * Merge the given array into the given Collection. - * - * @param array the array to merge (may be null) + * @param array the array to merge (may be null) * @param collection the target Collection to merge the array into */ @SuppressWarnings("unchecked") @@ -290,25 +94,26 @@ throw new IllegalArgumentException("Collection must not be null"); } Object[] arr = Objects.toObjectArray(array); - java.util.Collections.addAll(collection, arr); + for (Object elem : arr) { + collection.add(elem); + } } /** * Merge the given Properties instance into the given Map, * copying all properties (key-value pairs) over. *

    Uses Properties.propertyNames() to even catch * default properties linked into the original Properties instance. - * * @param props the Properties instance to merge (may be null) - * @param map the target Map to merge the properties into + * @param map the target Map to merge the properties into */ @SuppressWarnings("unchecked") public static void mergePropertiesIntoMap(Properties props, Map map) { if (map == null) { throw new IllegalArgumentException("Map must not be null"); } if (props != null) { - for (Enumeration en = props.propertyNames(); en.hasMoreElements(); ) { + for (Enumeration en = props.propertyNames(); en.hasMoreElements();) { String key = (String) en.nextElement(); Object value = props.getProperty(key); if (value == null) { @@ -323,9 +128,8 @@ /** * Check whether the given Iterator contains the given element. - * * @param iterator the Iterator to check - * @param element the element to look for + * @param element the element to look for * @return true if found, false else */ public static boolean contains(Iterator iterator, Object element) { @@ -342,9 +146,8 @@ /** * Check whether the given Enumeration contains the given element. - * * @param enumeration the Enumeration to check - * @param element the element to look for + * @param element the element to look for * @return true if found, false else */ public static boolean contains(Enumeration enumeration, Object element) { @@ -363,9 +166,8 @@ * Check whether the given Collection contains the given element instance. *

    Enforces the given instance to be present, rather than returning * true for an equal element as well. - * * @param collection the Collection to check - * @param element the element to look for + * @param element the element to look for * @return true if found, false else */ public static boolean containsInstance(Collection collection, Object element) { @@ -382,8 +184,7 @@ /** * Return true if any element in 'candidates' is * contained in 'source'; otherwise returns false. - * - * @param source the source Collection + * @param source the source Collection * @param candidates the candidates to search for * @return whether any of the candidates has been found */ @@ -404,8 +205,7 @@ * 'source'. If no element in 'candidates' is present in * 'source' returns null. Iteration order is * {@link Collection} implementation specific. - * - * @param source the source Collection + * @param source the source Collection * @param candidates the candidates to search for * @return the first present object, or null if not found */ @@ -423,10 +223,8 @@ /** * Find a single value of the given type in the given Collection. - * * @param collection the Collection to search - * @param type the type to look for - * @param the generic type parameter for {@code type} + * @param type the type to look for * @return a value of the given type found if there is a clear match, * or null if none or more than one such value found */ @@ -452,9 +250,8 @@ * Find a single value of one of the given types in the given Collection: * searching the Collection for a value of the first type, then * searching for a value of the second type, etc. - * * @param collection the collection to search - * @param types the types to look for, in prioritized order + * @param types the types to look for, in prioritized order * @return a value of one of the given types found if there is a clear match, * or null if none or more than one such value found */ @@ -473,7 +270,6 @@ /** * Determine whether the given Collection only contains a single unique object. - * * @param collection the Collection to check * @return true if the collection contains a single reference or * multiple references to the same instance, false else @@ -488,7 +284,8 @@ if (!hasCandidate) { hasCandidate = true; candidate = elem; - } else if (candidate != elem) { + } + else if (candidate != elem) { return false; } } @@ -497,7 +294,6 @@ /** * Find the common element type of the given Collection, if any. - * * @param collection the Collection to check * @return the common element type, or null if no clear * common type has been found (or the collection was empty) @@ -511,7 +307,8 @@ if (val != null) { if (candidate == null) { candidate = val.getClass(); - } else if (candidate != val.getClass()) { + } + else if (candidate != val.getClass()) { return null; } } @@ -523,15 +320,9 @@ * Marshal the elements from the given enumeration into an array of the given type. * Enumeration elements must be assignable to the type of the given array. The array * returned will be a different instance than the array given. - * - * @param enumeration the collection to convert to an array - * @param array an array instance that matches the type of array to return - * @param the element type of the array that will be created - * @param the element type contained within the enumeration. - * @return a new array of type {@code A} that contains the elements in the specified {@code enumeration}. */ - public static A[] toArray(Enumeration enumeration, A[] array) { - ArrayList elements = new ArrayList<>(); + public static A[] toArray(Enumeration enumeration, A[] array) { + ArrayList elements = new ArrayList(); while (enumeration.hasMoreElements()) { elements.add(enumeration.nextElement()); } @@ -540,21 +331,19 @@ /** * Adapt an enumeration to an iterator. - * * @param enumeration the enumeration - * @param the type of elements in the enumeration * @return the iterator */ public static Iterator toIterator(Enumeration enumeration) { - return new EnumerationIterator<>(enumeration); + return new EnumerationIterator(enumeration); } /** * Iterator wrapping an Enumeration. */ private static class EnumerationIterator implements Iterator { - private final Enumeration enumeration; + private Enumeration enumeration; public EnumerationIterator(Enumeration enumeration) { this.enumeration = enumeration; Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Conjunctor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/DateFormats.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/DateFormats.java (.../DateFormats.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/DateFormats.java (.../DateFormats.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -22,15 +22,10 @@ import java.util.TimeZone; /** - * Utility methods to format and parse date strings. - * * @since 0.10.0 */ -public final class DateFormats { +public class DateFormats { - private DateFormats() { - } // prevent instantiation - private static final String ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'"; private static final String ISO_8601_MILLIS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; @@ -53,40 +48,17 @@ } }; - /** - * Return an ISO-8601-formatted string with millisecond precision representing the - * specified {@code date}. - * - * @param date the date for which to create an ISO-8601-formatted string - * @return the date represented as an ISO-8601-formatted string with millisecond precision. - */ public static String formatIso8601(Date date) { return formatIso8601(date, true); } - /** - * Returns an ISO-8601-formatted string with optional millisecond precision for the specified - * {@code date}. - * - * @param date the date for which to create an ISO-8601-formatted string - * @param includeMillis whether to include millisecond notation within the string. - * @return the date represented as an ISO-8601-formatted string with optional millisecond precision. - */ public static String formatIso8601(Date date, boolean includeMillis) { if (includeMillis) { return ISO_8601_MILLIS.get().format(date); } return ISO_8601.get().format(date); } - /** - * Parse the specified ISO-8601-formatted date string and return the corresponding {@link Date} instance. The - * date string may optionally contain millisecond notation, and those milliseconds will be represented accordingly. - * - * @param s the ISO-8601-formatted string to parse - * @return the string's corresponding {@link Date} instance. - * @throws ParseException if the specified date string is not a validly-formatted ISO-8601 string. - */ public static Date parseIso8601Date(String s) throws ParseException { Assert.notNull(s, "String argument cannot be null."); if (s.lastIndexOf('.') > -1) { //assume ISO-8601 with milliseconds Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/InstantiationException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/InstantiationException.java (.../InstantiationException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/InstantiationException.java (.../InstantiationException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,19 +16,11 @@ package io.jsonwebtoken.lang; /** - * {@link RuntimeException} equivalent of {@link java.lang.InstantiationException}. - * * @since 0.1 */ public class InstantiationException extends RuntimeException { - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ - public InstantiationException(String message, Throwable cause) { - super(message, cause); + public InstantiationException(String s, Throwable t) { + super(s, t); } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/MapMutator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Maps.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Maps.java (.../Maps.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Maps.java (.../Maps.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -21,13 +21,11 @@ /** * Utility class to help with the manipulation of working with Maps. - * * @since 0.11.0 */ public final class Maps { - private Maps() { - } //prevent instantiation + private Maps() {} //prevent instantiation /** * Creates a new map builder with a single entry. @@ -37,12 +35,11 @@ * // ... * .build(); * } - * - * @param key the key of an map entry to be added + * @param key the key of an map entry to be added * @param value the value of map entry to be added * @param the maps key type * @param the maps value type - * @return a new map builder with a single entry. + * Creates a new map builder with a single entry. */ public static MapBuilder of(K key, V value) { return new HashMapBuilder().and(key, value); @@ -56,24 +53,21 @@ * // ... * .build(); * } - * * @param the maps key type * @param the maps value type */ - public interface MapBuilder extends Builder> { + public interface MapBuilder { /** * Add a new entry to this map builder - * - * @param key the key of an map entry to be added + * @param key the key of an map entry to be added * @param value the value of map entry to be added * @return the current MapBuilder to allow for method chaining. */ MapBuilder and(K key, V value); /** - * Returns the resulting Map object from this MapBuilder. - * - * @return the resulting Map object from this MapBuilder. + * Returns a the resulting Map object from this MapBuilder. + * @return Returns a the resulting Map object from this MapBuilder. */ Map build(); } @@ -86,7 +80,6 @@ data.put(key, value); return this; } - public Map build() { return Collections.unmodifiableMap(data); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/NestedCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Objects.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Objects.java (.../Objects.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Objects.java (.../Objects.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,30 +16,22 @@ package io.jsonwebtoken.lang; import java.io.Closeable; -import java.io.Flushable; import java.io.IOException; import java.lang.reflect.Array; import java.util.Arrays; -import java.util.Collection; -import java.util.Map; -/** - * Utility methods for working with object instances to reduce pattern repetition and otherwise - * increased cyclomatic complexity. - */ public final class Objects { - private Objects() { - } //prevent instantiation + private Objects(){} //prevent instantiation private static final int INITIAL_HASH = 7; - private static final int MULTIPLIER = 31; + private static final int MULTIPLIER = 31; - private static final String EMPTY_STRING = ""; - private static final String NULL_STRING = "null"; - private static final String ARRAY_START = "{"; - private static final String ARRAY_END = "}"; - private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; + private static final String EMPTY_STRING = ""; + private static final String NULL_STRING = "null"; + private static final String ARRAY_START = "{"; + private static final String ARRAY_END = "}"; + private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; private static final String ARRAY_ELEMENT_SEPARATOR = ", "; /** @@ -81,68 +73,36 @@ } /** - * Returns {@code true} if the specified argument is an Object or primitive array, {@code false} otherwise. + * Determine whether the given object is an array: + * either an Object array or a primitive array. * - * @param obj the object instance to check - * @return {@code true} if the specified argument is an Object or primitive array, {@code false} otherwise. + * @param obj the object to check */ public static boolean isArray(Object obj) { return (obj != null && obj.getClass().isArray()); } /** - * Returns {@code true} if the specified argument: - *

      - *
    1. is {@code null}, or
    2. - *
    3. is a CharSequence and {@link Strings#hasText(CharSequence)} is {@code false}, or
    4. - *
    5. is a Collection or Map with zero size, or
    6. - *
    7. is an empty array
    8. - *
    - *

    or {@code false} otherwise.

    + * Determine whether the given array is empty: + * i.e. null or of zero length. * - * @param v object to check - * @return {@code true} if the specified argument is empty, {@code false} otherwise. - * @since 0.12.0 - */ - public static boolean isEmpty(Object v) { - return v == null || - (v instanceof CharSequence && !Strings.hasText((CharSequence) v)) || - (v instanceof Collection && Collections.isEmpty((Collection) v)) || - (v instanceof Map && Collections.isEmpty((Map) v)) || - (v.getClass().isArray() && Array.getLength(v) == 0); - } - - /** - * {@code true} if the specified array is null or zero length, {@code false} if populated. - * * @param array the array to check - * @return {@code true} if the specified array is null or zero length, {@code false} if populated. */ public static boolean isEmpty(Object[] array) { return (array == null || array.length == 0); } /** - * Returns {@code true} if the specified byte array is null or of zero length, {@code false} if populated. + * Returns {@code true} if the specified byte array is null or of zero length, {@code false} otherwise. * * @param array the byte array to check - * @return {@code true} if the specified byte array is null or of zero length, {@code false} if populated. + * @return {@code true} if the specified byte array is null or of zero length, {@code false} otherwise. */ public static boolean isEmpty(byte[] array) { return array == null || array.length == 0; } /** - * Returns {@code true} if the specified character array is null or of zero length, {@code false} otherwise. - * - * @param chars the character array to check - * @return {@code true} if the specified character array is null or of zero length, {@code false} otherwise. - */ - public static boolean isEmpty(char[] chars) { - return chars == null || chars.length == 0; - } - - /** * Check whether the given array contains the given element. * * @param array the array to check (may be null, @@ -185,8 +145,8 @@ public static boolean containsConstant(Enum[] enumValues, String constant, boolean caseSensitive) { for (Enum candidate : enumValues) { if (caseSensitive ? - candidate.toString().equals(constant) : - candidate.toString().equalsIgnoreCase(constant)) { + candidate.toString().equals(constant) : + candidate.toString().equalsIgnoreCase(constant)) { return true; } } @@ -199,7 +159,6 @@ * @param the concrete Enum type * @param enumValues the array of all Enum constants in question, usually per Enum.values() * @param constant the constant to get the enum value of - * @return the enum constant of the specified enum type with the specified case-insensitive name * @throws IllegalArgumentException if the given constant is not found in the given array * of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to * avoid this exception. @@ -211,18 +170,16 @@ } } throw new IllegalArgumentException( - String.format("constant [%s] does not exist in enum type %s", - constant, enumValues.getClass().getComponentType().getName())); + String.format("constant [%s] does not exist in enum type %s", + constant, enumValues.getClass().getComponentType().getName())); } /** * Append the given object to the given array, returning a new array * consisting of the input array contents plus the given object. * * @param array the array to append to (can be null) - * @param
    the type of each element in the specified {@code array} * @param obj the object to append - * @param the type of the specified object, which must be equal to or extend the <A> type. * @return the new array (of the same component type; never null) */ public static A[] addObjectToArray(A[] array, O obj) { @@ -340,8 +297,6 @@ * methods for arrays in this class. If the object is null, * this method returns 0. * - * @param obj the object to use for obtaining a hashcode - * @return the object's hashcode, which could be 0 if the object is null. * @see #nullSafeHashCode(Object[]) * @see #nullSafeHashCode(boolean[]) * @see #nullSafeHashCode(byte[]) @@ -391,11 +346,8 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the array to obtain a hashcode - * @return the array's hashcode, which could be 0 if the array is null. */ - public static int nullSafeHashCode(Object... array) { + public static int nullSafeHashCode(Object[] array) { if (array == null) { return 0; } @@ -410,9 +362,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the boolean array to obtain a hashcode - * @return the boolean array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(boolean[] array) { if (array == null) { @@ -429,9 +378,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the byte array to obtain a hashcode - * @return the byte array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(byte[] array) { if (array == null) { @@ -448,9 +394,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the char array to obtain a hashcode - * @return the char array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(char[] array) { if (array == null) { @@ -467,9 +410,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the double array to obtain a hashcode - * @return the double array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(double[] array) { if (array == null) { @@ -486,9 +426,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the float array to obtain a hashcode - * @return the float array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(float[] array) { if (array == null) { @@ -505,9 +442,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the int array to obtain a hashcode - * @return the int array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(int[] array) { if (array == null) { @@ -524,9 +458,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the long array to obtain a hashcode - * @return the long array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(long[] array) { if (array == null) { @@ -543,9 +474,6 @@ /** * Return a hash code based on the contents of the specified array. * If array is null, this method returns 0. - * - * @param array the short array to obtain a hashcode - * @return the short array's hashcode, which could be 0 if the array is null. */ public static int nullSafeHashCode(short[] array) { if (array == null) { @@ -562,8 +490,6 @@ /** * Return the same value as {@link Boolean#hashCode()}. * - * @param bool the boolean to get a hashcode - * @return the same value as {@link Boolean#hashCode()}. * @see Boolean#hashCode() */ public static int hashCode(boolean bool) { @@ -573,8 +499,6 @@ /** * Return the same value as {@link Double#hashCode()}. * - * @param dbl the double to get a hashcode - * @return the same value as {@link Double#hashCode()}. * @see Double#hashCode() */ public static int hashCode(double dbl) { @@ -585,8 +509,6 @@ /** * Return the same value as {@link Float#hashCode()}. * - * @param flt the float to get a hashcode - * @return the same value as {@link Float#hashCode()}. * @see Float#hashCode() */ public static int hashCode(float flt) { @@ -596,8 +518,6 @@ /** * Return the same value as {@link Long#hashCode()}. * - * @param lng the long to get a hashcode - * @return the same value as {@link Long#hashCode()}. * @see Long#hashCode() */ public static int hashCode(long lng) { @@ -612,8 +532,9 @@ /** * Return a String representation of an object's overall identity. * - * @param obj the object (which may be null). - * @return the object's identity as String representation, or an empty String if the object was null. + * @param obj the object (may be null) + * @return the object's identity as String representation, + * or an empty String if the object was null */ public static String identityToString(Object obj) { if (obj == null) { @@ -988,12 +909,6 @@ return sb.toString(); } - /** - * Iterate over the specified {@link Closeable} instances, invoking - * {@link Closeable#close()} on each one, ignoring any potential {@link IOException}s. - * - * @param closeables the closeables to close. - */ public static void nullSafeClose(Closeable... closeables) { if (closeables == null) { return; @@ -1009,23 +924,4 @@ } } } - - /** - * Iterate over the specified {@link Flushable} instances, invoking - * {@link Flushable#flush()} on each one, ignoring any potential {@link IOException}s. - * - * @param flushables the flushables to flush. - * @since 0.12.0 - */ - public static void nullSafeFlush(Flushable... flushables) { - if (flushables == null) return; - for (Flushable flushable : flushables) { - if (flushable != null) { - try { - flushable.flush(); - } catch (IOException ignored) { - } - } - } - } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Registry.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/RuntimeEnvironment.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/RuntimeEnvironment.java (.../RuntimeEnvironment.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/RuntimeEnvironment.java (.../RuntimeEnvironment.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -19,59 +19,38 @@ import java.security.Security; import java.util.concurrent.atomic.AtomicBoolean; -/** - * No longer used by JJWT. Will be removed before the 1.0 final release. - * - * @deprecated since 0.12.0. will be removed before the 1.0 final release. - */ -@Deprecated public final class RuntimeEnvironment { - private RuntimeEnvironment() { - } //prevent instantiation + private RuntimeEnvironment(){} //prevent instantiation private static final String BC_PROVIDER_CLASS_NAME = "org.bouncycastle.jce.provider.BouncyCastleProvider"; private static final AtomicBoolean bcLoaded = new AtomicBoolean(false); - /** - * {@code true} if BouncyCastle is in the runtime classpath, {@code false} otherwise. - * - * @deprecated since 0.12.0. will be removed before the 1.0 final release. - */ - @Deprecated public static final boolean BOUNCY_CASTLE_AVAILABLE = Classes.isAvailable(BC_PROVIDER_CLASS_NAME); - /** - * Register BouncyCastle as a JCA provider in the system's {@link Security#getProviders() Security Providers} list - * if BouncyCastle is in the runtime classpath. - * - * @deprecated since 0.12.0. will be removed before the 1.0 final release. - */ - @Deprecated public static void enableBouncyCastleIfPossible() { if (!BOUNCY_CASTLE_AVAILABLE || bcLoaded.get()) { return; } try { - Class clazz = Classes.forName(BC_PROVIDER_CLASS_NAME); + Class clazz = Classes.forName(BC_PROVIDER_CLASS_NAME); //check to see if the user has already registered the BC provider: Provider[] providers = Security.getProviders(); - for (Provider provider : providers) { + for(Provider provider : providers) { if (clazz.isInstance(provider)) { bcLoaded.set(true); return; } } //bc provider not enabled - add it: - Provider provider = Classes.newInstance(clazz); - Security.addProvider(provider); + Security.addProvider((Provider)Classes.newInstance(clazz)); bcLoaded.set(true); } catch (UnknownClassException e) { Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Strings.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Strings.java (.../Strings.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Strings.java (.../Strings.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,10 +15,7 @@ */ package io.jsonwebtoken.lang; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -32,19 +29,8 @@ import java.util.StringTokenizer; import java.util.TreeSet; -/** - * Utility methods for working with Strings to reduce pattern repetition and otherwise - * increased cyclomatic complexity. - */ public final class Strings { - /** - * Empty String, equal to "". - */ - public static final String EMPTY = ""; - - private static final CharBuffer EMPTY_BUF = CharBuffer.wrap(EMPTY); - private static final String FOLDER_SEPARATOR = "/"; private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; @@ -55,13 +41,9 @@ private static final char EXTENSION_SEPARATOR = '.'; - /** - * Convenience alias for {@link StandardCharsets#UTF_8}. - */ - public static final Charset UTF_8 = StandardCharsets.UTF_8; + public static final Charset UTF_8 = Charset.forName("UTF-8"); - private Strings() { - } //prevent instantiation + private Strings(){} //prevent instantiation //--------------------------------------------------------------------- // General convenience methods for working with Strings @@ -70,13 +52,12 @@ /** * Check that the given CharSequence is neither null nor of length 0. * Note: Will return true for a CharSequence that purely consists of whitespace. - *
    +     * 

          * Strings.hasLength(null) = false
          * Strings.hasLength("") = false
          * Strings.hasLength(" ") = true
          * Strings.hasLength("Hello") = true
          * 
    - * * @param str the CharSequence to check (may be null) * @return true if the CharSequence is not null and has length * @see #hasText(String) @@ -88,7 +69,6 @@ /** * Check that the given String is neither null nor of length 0. * Note: Will return true for a String that purely consists of whitespace. - * * @param str the String to check (may be null) * @return true if the String is not null and has length * @see #hasLength(CharSequence) @@ -101,14 +81,13 @@ * Check whether the given CharSequence has actual text. * More specifically, returns true if the string not null, * its length is greater than 0, and it contains at least one non-whitespace character. - *
    +     * 

          * Strings.hasText(null) = false
          * Strings.hasText("") = false
          * Strings.hasText(" ") = false
          * Strings.hasText("12345") = true
          * Strings.hasText(" 12345 ") = true
          * 
    - * * @param str the CharSequence to check (may be null) * @return true if the CharSequence is not null, * its length is greater than 0, and it does not contain whitespace only @@ -131,7 +110,6 @@ * Check whether the given String has actual text. * More specifically, returns true if the string not null, * its length is greater than 0, and it contains at least one non-whitespace character. - * * @param str the String to check (may be null) * @return true if the String is not null, its length is * greater than 0, and it does not contain whitespace only @@ -143,7 +121,6 @@ /** * Check whether the given CharSequence contains any whitespace characters. - * * @param str the CharSequence to check (may be null) * @return true if the CharSequence is not empty and * contains at least 1 whitespace character @@ -164,7 +141,6 @@ /** * Check whether the given String contains any whitespace characters. - * * @param str the String to check (may be null) * @return true if the String is not empty and * contains at least 1 whitespace character @@ -176,57 +152,40 @@ /** * Trim leading and trailing whitespace from the given String. - * * @param str the String to check * @return the trimmed String * @see java.lang.Character#isWhitespace */ public static String trimWhitespace(String str) { - return (String) trimWhitespace((CharSequence) str); + return (String) trimWhitespace((CharSequence)str); } - - + + private static CharSequence trimWhitespace(CharSequence str) { if (!hasLength(str)) { return str; } final int length = str.length(); int start = 0; - while (start < length && Character.isWhitespace(str.charAt(start))) { + while (start < length && Character.isWhitespace(str.charAt(start))) { start++; } - - int end = length; + + int end = length; while (start < length && Character.isWhitespace(str.charAt(end - 1))) { end--; } - + return ((start > 0) || (end < length)) ? str.subSequence(start, end) : str; } - /** - * Returns the specified string without leading or trailing whitespace, or {@code null} if there are no remaining - * characters. - * - * @param str the string to clean - * @return the specified string without leading or trailing whitespace, or {@code null} if there are no remaining - * characters. - */ public static String clean(String str) { - CharSequence result = clean((CharSequence) str); - - return result != null ? result.toString() : null; + CharSequence result = clean((CharSequence) str); + + return result!=null?result.toString():null; } - - /** - * Returns the specified {@code CharSequence} without leading or trailing whitespace, or {@code null} if there are - * no remaining characters. - * - * @param str the {@code CharSequence} to clean - * @return the specified string without leading or trailing whitespace, or {@code null} if there are no remaining - * characters. - */ + public static CharSequence clean(CharSequence str) { str = trimWhitespace(str); if (!hasLength(str)) { @@ -236,125 +195,8 @@ } /** - * Returns the specified string's UTF-8 bytes, or {@code null} if the string is {@code null}. - * - * @param s the string to obtain UTF-8 bytes - * @return the specified string's UTF-8 bytes, or {@code null} if the string is {@code null}. - * @since 0.12.0 - */ - public static byte[] utf8(CharSequence s) { - if (s == null) return null; - CharBuffer cb = s instanceof CharBuffer ? (CharBuffer) s : CharBuffer.wrap(s); - cb.mark(); - ByteBuffer buf = UTF_8.encode(cb); - byte[] bytes = new byte[buf.remaining()]; - buf.get(bytes); - cb.reset(); - return bytes; - } - - /** - * Returns {@code new String(utf8Bytes, StandardCharsets.UTF_8)}. - * - * @param utf8Bytes UTF-8 bytes to use with the {@code String} constructor. - * @return {@code new String(utf8Bytes, StandardCharsets.UTF_8)}. - * @since 0.12.0 - */ - public static String utf8(byte[] utf8Bytes) { - return new String(utf8Bytes, UTF_8); - } - - /** - * Returns {@code new String(asciiBytes, StandardCharsets.US_ASCII)}. - * - * @param asciiBytes US_ASCII bytes to use with the {@code String} constructor. - * @return {@code new String(asciiBytes, StandardCharsets.US_ASCII)}. - * @since 0.12.0 - */ - public static String ascii(byte[] asciiBytes) { - return new String(asciiBytes, StandardCharsets.US_ASCII); - } - - /** - * Returns the {@link StandardCharsets#US_ASCII US_ASCII}-encoded bytes of the specified {@code CharSequence}. - * - * @param s the {@code CharSequence} to encode to {@code US_ASCII}. - * @return the {@link StandardCharsets#US_ASCII US_ASCII}-encoded bytes of the specified {@code CharSequence}. - */ - public static byte[] ascii(CharSequence s) { - byte[] bytes = null; - if (s != null) { - CharBuffer cb = s instanceof CharBuffer ? (CharBuffer) s : CharBuffer.wrap(s); - ByteBuffer buf = StandardCharsets.US_ASCII.encode(cb); - bytes = new byte[buf.remaining()]; - buf.get(bytes); - } - return bytes; - } - - /** - * Returns a {@code CharBuffer} that wraps {@code seq}, or an empty buffer if {@code seq} is null. If - * {@code seq} is already a {@code CharBuffer}, it is returned unmodified. - * - * @param seq the {@code CharSequence} to wrap. - * @return a {@code CharBuffer} that wraps {@code seq}, or an empty buffer if {@code seq} is null. - */ - public static CharBuffer wrap(CharSequence seq) { - if (!hasLength(seq)) return EMPTY_BUF; - if (seq instanceof CharBuffer) return (CharBuffer) seq; - return CharBuffer.wrap(seq); - } - - /** - * Returns a String representation (1s and 0s) of the specified byte. - * - * @param b the byte to represent as 1s and 0s. - * @return a String representation (1s and 0s) of the specified byte. - */ - public static String toBinary(byte b) { - String bString = Integer.toBinaryString(b & 0xFF); - return String.format("%8s", bString).replace((char) Character.SPACE_SEPARATOR, '0'); - } - - /** - * Returns a String representation (1s and 0s) of the specified byte array. - * - * @param bytes the bytes to represent as 1s and 0s. - * @return a String representation (1s and 0s) of the specified byte array. - */ - public static String toBinary(byte[] bytes) { - StringBuilder sb = new StringBuilder(19); //16 characters + 3 space characters - for (byte b : bytes) { - if (sb.length() > 0) { - sb.append((char) Character.SPACE_SEPARATOR); - } - String val = toBinary(b); - sb.append(val); - } - return sb.toString(); - } - - /** - * Returns a hexadecimal String representation of the specified byte array. - * - * @param bytes the bytes to represent as a hexidecimal string. - * @return a hexadecimal String representation of the specified byte array. - */ - public static String toHex(byte[] bytes) { - StringBuilder result = new StringBuilder(); - for (byte temp : bytes) { - if (result.length() > 0) { - result.append((char) Character.SPACE_SEPARATOR); - } - result.append(String.format("%02x", temp)); - } - return result.toString(); - } - - /** * Trim all whitespace from the given String: - * leading, trailing, and intermediate characters. - * + * leading, trailing, and inbetween characters. * @param str the String to check * @return the trimmed String * @see java.lang.Character#isWhitespace @@ -368,7 +210,8 @@ while (sb.length() > index) { if (Character.isWhitespace(sb.charAt(index))) { sb.deleteCharAt(index); - } else { + } + else { index++; } } @@ -377,7 +220,6 @@ /** * Trim leading whitespace from the given String. - * * @param str the String to check * @return the trimmed String * @see java.lang.Character#isWhitespace @@ -395,7 +237,6 @@ /** * Trim trailing whitespace from the given String. - * * @param str the String to check * @return the trimmed String * @see java.lang.Character#isWhitespace @@ -412,9 +253,8 @@ } /** - * Trim all occurrences of the supplied leading character from the given String. - * - * @param str the String to check + * Trim all occurences of the supplied leading character from the given String. + * @param str the String to check * @param leadingCharacter the leading character to be trimmed * @return the trimmed String */ @@ -430,9 +270,8 @@ } /** - * Trim all occurrences of the supplied trailing character from the given String. - * - * @param str the String to check + * Trim all occurences of the supplied trailing character from the given String. + * @param str the String to check * @param trailingCharacter the trailing character to be trimmed * @return the trimmed String */ @@ -449,34 +288,32 @@ /** - * Returns {@code true} if the given string starts with the specified case-insensitive prefix, {@code false} otherwise. - * - * @param str the String to check + * Test if the given String starts with the specified prefix, + * ignoring upper/lower case. + * @param str the String to check * @param prefix the prefix to look for - * @return {@code true} if the given string starts with the specified case-insensitive prefix, {@code false} otherwise. * @see java.lang.String#startsWith */ public static boolean startsWithIgnoreCase(String str, String prefix) { if (str == null || prefix == null) { return false; } - if (str.length() < prefix.length()) { - return false; - } if (str.startsWith(prefix)) { return true; } + if (str.length() < prefix.length()) { + return false; + } String lcStr = str.substring(0, prefix.length()).toLowerCase(); String lcPrefix = prefix.toLowerCase(); return lcStr.equals(lcPrefix); } /** - * Returns {@code true} if the given string ends with the specified case-insensitive suffix, {@code false} otherwise. - * - * @param str the String to check + * Test if the given String ends with the specified suffix, + * ignoring upper/lower case. + * @param str the String to check * @param suffix the suffix to look for - * @return {@code true} if the given string ends with the specified case-insensitive suffix, {@code false} otherwise. * @see java.lang.String#endsWith */ public static boolean endsWithIgnoreCase(String str, String suffix) { @@ -496,12 +333,11 @@ } /** - * Returns {@code true} if the given string matches the given substring at the given index, {@code false} otherwise. - * - * @param str the original string (or StringBuilder) - * @param index the index in the original string to start matching against + * Test whether the given string matches the given substring + * at the given index. + * @param str the original string (or StringBuilder) + * @param index the index in the original string to start matching against * @param substring the substring to match at the given index - * @return {@code true} if the given string matches the given substring at the given index, {@code false} otherwise. */ public static boolean substringMatch(CharSequence str, int index, CharSequence substring) { for (int j = 0; j < substring.length(); j++) { @@ -514,11 +350,9 @@ } /** - * Returns the number of occurrences the substring {@code sub} appears in string {@code str}. - * + * Count the occurrences of the substring in string s. * @param str string to search in. Return 0 if this is null. * @param sub string to search for. Return 0 if this is null. - * @return the number of occurrences the substring {@code sub} appears in string {@code str}. */ public static int countOccurrencesOf(String str, String sub) { if (str == null || sub == null || str.length() == 0 || sub.length() == 0) { @@ -535,10 +369,9 @@ } /** - * Replace all occurrences of a substring within a string with + * Replace all occurences of a substring within a string with * another string. - * - * @param inString String to examine + * @param inString String to examine * @param oldPattern String to replace * @param newPattern String to insert * @return a String with the replacements @@ -565,9 +398,8 @@ /** * Delete all occurrences of the given substring. - * * @param inString the original String - * @param pattern the pattern to delete all occurrences of + * @param pattern the pattern to delete all occurrences of * @return the resulting String */ public static String delete(String inString, String pattern) { @@ -576,10 +408,9 @@ /** * Delete any character in a given String. - * - * @param inString the original String + * @param inString the original String * @param charsToDelete a set of characters to delete. - * E.g. "az\n" will delete 'a's, 'z's and new lines. + * E.g. "az\n" will delete 'a's, 'z's and new lines. * @return the resulting String */ public static String deleteAny(String inString, String charsToDelete) { @@ -603,7 +434,6 @@ /** * Quote the given String with single quotes. - * * @param str the input String (e.g. "myString") * @return the quoted String (e.g. "'myString'"), * or null if the input was null @@ -615,7 +445,6 @@ /** * Turn the given Object into a String with single quotes * if it is a String; keeping the Object as-is else. - * * @param obj the input Object (e.g. "myString") * @return the quoted String (e.g. "'myString'"), * or the input object as-is if not a String @@ -627,9 +456,7 @@ /** * Unqualify a string qualified by a '.' dot character. For example, * "this.name.is.qualified", returns "qualified". - * * @param qualifiedName the qualified name - * @return an unqualified string by stripping all previous text before (and including) the last period character. */ public static String unqualify(String qualifiedName) { return unqualify(qualifiedName, '.'); @@ -638,10 +465,8 @@ /** * Unqualify a string qualified by a separator character. For example, * "this:name:is:qualified" returns "qualified" if using a ':' separator. - * * @param qualifiedName the qualified name - * @param separator the separator - * @return an unqualified string by stripping all previous text before and including the last {@code separator} character. + * @param separator the separator */ public static String unqualify(String qualifiedName, char separator) { return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1); @@ -651,7 +476,6 @@ * Capitalize a String, changing the first letter to * upper case as per {@link Character#toUpperCase(char)}. * No other letters are changed. - * * @param str the String to capitalize, may be null * @return the capitalized String, null if null */ @@ -663,7 +487,6 @@ * Uncapitalize a String, changing the first letter to * lower case as per {@link Character#toLowerCase(char)}. * No other letters are changed. - * * @param str the String to uncapitalize, may be null * @return the uncapitalized String, null if null */ @@ -678,7 +501,8 @@ StringBuilder sb = new StringBuilder(str.length()); if (capitalize) { sb.append(Character.toUpperCase(str.charAt(0))); - } else { + } + else { sb.append(Character.toLowerCase(str.charAt(0))); } sb.append(str.substring(1)); @@ -688,7 +512,6 @@ /** * Extract the filename from the given path, * e.g. "mypath/myfile.txt" -> "myfile.txt". - * * @param path the file path (may be null) * @return the extracted filename, or null if none */ @@ -703,7 +526,6 @@ /** * Extract the filename extension from the given path, * e.g. "mypath/myfile.txt" -> "txt". - * * @param path the file path (may be null) * @return the extracted filename extension, or null if none */ @@ -725,7 +547,6 @@ /** * Strip the filename extension from the given path, * e.g. "mypath/myfile.txt" -> "mypath/myfile". - * * @param path the file path (may be null) * @return the path with stripped filename extension, * or null if none @@ -748,10 +569,9 @@ /** * Apply the given relative path to the given path, * assuming standard Java folder separation (i.e. "/" separators). - * - * @param path the path to start from (usually a full file path) + * @param path the path to start from (usually a full file path) * @param relativePath the relative path to apply - * (relative to the full file path above) + * (relative to the full file path above) * @return the full file path that results from applying the relative path */ public static String applyRelativePath(String path, String relativePath) { @@ -762,7 +582,8 @@ newPath += FOLDER_SEPARATOR; } return newPath + relativePath; - } else { + } + else { return relativePath; } } @@ -772,7 +593,6 @@ * inner simple dots. *

    The result is convenient for path comparison. For other uses, * notice that Windows separators ("\") are replaced by simple slashes. - * * @param path the original path * @return the normalized path */ @@ -805,14 +625,17 @@ String element = pathArray[i]; if (CURRENT_PATH.equals(element)) { // Points to current directory - drop it. - } else if (TOP_PATH.equals(element)) { + } + else if (TOP_PATH.equals(element)) { // Registering top path found. tops++; - } else { + } + else { if (tops > 0) { // Merging path element with element corresponding to top path. tops--; - } else { + } + else { // Normal path element found. pathElements.add(0, element); } @@ -829,7 +652,6 @@ /** * Compare two paths after normalization of them. - * * @param path1 first path for comparison * @param path2 second path for comparison * @return whether the two paths are equivalent after normalization @@ -841,10 +663,9 @@ /** * Parse the given localeString value into a {@link java.util.Locale}. *

    This is the inverse operation of {@link java.util.Locale#toString Locale's toString}. - * * @param localeString the locale string, following Locale's - * toString() format ("en", "en_UK", etc); - * also accepts spaces as separators, as an alternative to underscores + * toString() format ("en", "en_UK", etc); + * also accepts spaces as separators, as an alternative to underscores * @return a corresponding Locale instance */ public static Locale parseLocaleString(String localeString) { @@ -871,15 +692,15 @@ for (int i = 0; i < localePart.length(); i++) { char ch = localePart.charAt(i); if (ch != '_' && ch != ' ' && !Character.isLetterOrDigit(ch)) { - throw new IllegalArgumentException("Locale part \"" + localePart + "\" contains invalid characters"); + throw new IllegalArgumentException( + "Locale part \"" + localePart + "\" contains invalid characters"); } } } /** * Determine the RFC 3066 compliant language tag, * as used for the HTTP "Accept-Language" header. - * * @param locale the Locale to transform to a language tag * @return the RFC 3066 compliant language tag as String */ @@ -895,14 +716,13 @@ /** * Append the given String to the given String array, returning a new array * consisting of the input array contents plus the given String. - * * @param array the array to append to (can be null) - * @param str the String to append + * @param str the String to append * @return the new array (never null) */ public static String[] addStringToArray(String[] array, String str) { if (Objects.isEmpty(array)) { - return new String[]{str}; + return new String[] {str}; } String[] newArr = new String[array.length + 1]; System.arraycopy(array, 0, newArr, 0, array.length); @@ -914,7 +734,6 @@ * Concatenate the given String arrays into one, * with overlapping array elements included twice. *

    The order of elements in the original arrays is preserved. - * * @param array1 the first array (can be null) * @param array2 the second array (can be null) * @return the new array (null if both given arrays were null) @@ -938,7 +757,6 @@ *

    The order of elements in the original arrays is preserved * (with the exception of overlapping elements, which are only * included on their first occurrence). - * * @param array1 the first array (can be null) * @param array2 the second array (can be null) * @return the new array (null if both given arrays were null) @@ -962,7 +780,6 @@ /** * Turn given source String array into sorted array. - * * @param array the source array * @return the sorted array (never null) */ @@ -977,7 +794,6 @@ /** * Copy the given Collection into a String array. * The Collection must contain String elements only. - * * @param collection the Collection to copy * @return the String array (null if the passed-in * Collection was null) @@ -992,7 +808,6 @@ /** * Copy the given Enumeration into a String array. * The Enumeration must contain String elements only. - * * @param enumeration the Enumeration to copy * @return the String array (null if the passed-in * Enumeration was null) @@ -1008,7 +823,6 @@ /** * Trim the elements of the given String array, * calling String.trim() on each of them. - * * @param array the original String array * @return the resulting array (of the same size) with trimmed elements */ @@ -1027,7 +841,6 @@ /** * Remove duplicate Strings from the given array. * Also sorts the array, as it uses a TreeSet. - * * @param array the String array * @return an array without duplicates, in natural sort order */ @@ -1045,8 +858,7 @@ /** * Split a String at the first occurrence of the delimiter. * Does not include the delimiter in the result. - * - * @param toSplit the string to split + * @param toSplit the string to split * @param delimiter to split the string up with * @return a two element array with index 0 being before the delimiter, and * index 1 being after the delimiter (neither element includes the delimiter); @@ -1062,7 +874,7 @@ } String beforeDelimiter = toSplit.substring(0, offset); String afterDelimiter = toSplit.substring(offset + delimiter.length()); - return new String[]{beforeDelimiter, afterDelimiter}; + return new String[] {beforeDelimiter, afterDelimiter}; } /** @@ -1071,8 +883,7 @@ * delimiter providing the key, and the right of the delimiter providing the value. *

    Will trim both the key and value before adding them to the * Properties instance. - * - * @param array the array to process + * @param array the array to process * @param delimiter to split each element using (typically the equals symbol) * @return a Properties instance representing the array contents, * or null if the array to process was null or empty @@ -1087,16 +898,16 @@ * delimiter providing the key, and the right of the delimiter providing the value. *

    Will trim both the key and value before adding them to the * Properties instance. - * - * @param array the array to process - * @param delimiter to split each element using (typically the equals symbol) + * @param array the array to process + * @param delimiter to split each element using (typically the equals symbol) * @param charsToDelete one or more characters to remove from each element - * prior to attempting the split operation (typically the quotation mark - * symbol), or null if no removal should occur + * prior to attempting the split operation (typically the quotation mark + * symbol), or null if no removal should occur * @return a Properties instance representing the array contents, * or null if the array to process was null or empty */ - public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter, String charsToDelete) { + public static Properties splitArrayElementsIntoProperties( + String[] array, String delimiter, String charsToDelete) { if (Objects.isEmpty(array)) { return null; @@ -1122,10 +933,9 @@ * delimiter characters. Each of those characters can be used to separate * tokens. A delimiter is always a single character; for multi-character * delimiters, consider using delimitedListToStringArray - * - * @param str the String to tokenize + * @param str the String to tokenize * @param delimiters the delimiter characters, assembled as String - * (each of those characters is individually considered as delimiter). + * (each of those characters is individually considered as delimiter). * @return an array of the tokens * @see java.util.StringTokenizer * @see java.lang.String#trim() @@ -1141,21 +951,21 @@ * delimiter characters. Each of those characters can be used to separate * tokens. A delimiter is always a single character; for multi-character * delimiters, consider using delimitedListToStringArray - * - * @param str the String to tokenize - * @param delimiters the delimiter characters, assembled as String - * (each of those characters is individually considered as delimiter) - * @param trimTokens trim the tokens via String's trim + * @param str the String to tokenize + * @param delimiters the delimiter characters, assembled as String + * (each of those characters is individually considered as delimiter) + * @param trimTokens trim the tokens via String's trim * @param ignoreEmptyTokens omit empty tokens from the result array - * (only applies to tokens that are empty after trimming; StringTokenizer - * will not consider subsequent delimiters as token in the first place). + * (only applies to tokens that are empty after trimming; StringTokenizer + * will not consider subsequent delimiters as token in the first place). * @return an array of the tokens (null if the input String * was null) * @see java.util.StringTokenizer * @see java.lang.String#trim() * @see #delimitedListToStringArray */ - public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) { + public static String[] tokenizeToStringArray( + String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) { if (str == null) { return null; @@ -1179,10 +989,9 @@ *

    A single delimiter can consists of more than one character: It will still * be considered as single delimiter string, rather than as bunch of potential * delimiter characters - in contrast to tokenizeToStringArray. - * - * @param str the input String + * @param str the input String * @param delimiter the delimiter between elements (this is a single delimiter, - * rather than a bunch individual delimiter characters) + * rather than a bunch individual delimiter characters) * @return an array of the tokens in the list * @see #tokenizeToStringArray */ @@ -1195,12 +1004,11 @@ *

    A single delimiter can consists of more than one character: It will still * be considered as single delimiter string, rather than as bunch of potential * delimiter characters - in contrast to tokenizeToStringArray. - * - * @param str the input String - * @param delimiter the delimiter between elements (this is a single delimiter, - * rather than a bunch individual delimiter characters) + * @param str the input String + * @param delimiter the delimiter between elements (this is a single delimiter, + * rather than a bunch individual delimiter characters) * @param charsToDelete a set of characters to delete. Useful for deleting unwanted - * line breaks: e.g. "\r\n\f" will delete all new lines and line feeds in a String. + * line breaks: e.g. "\r\n\f" will delete all new lines and line feeds in a String. * @return an array of the tokens in the list * @see #tokenizeToStringArray */ @@ -1209,14 +1017,15 @@ return new String[0]; } if (delimiter == null) { - return new String[]{str}; + return new String[] {str}; } List result = new ArrayList(); if ("".equals(delimiter)) { for (int i = 0; i < str.length(); i++) { result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); } - } else { + } + else { int pos = 0; int delPos; while ((delPos = str.indexOf(delimiter, pos)) != -1) { @@ -1233,7 +1042,6 @@ /** * Convert a CSV list into an array of Strings. - * * @param str the input String * @return an array of Strings, or the empty array in case of empty input */ @@ -1244,7 +1052,6 @@ /** * Convenience method to convert a CSV string list to a set. * Note that this will suppress duplicates. - * * @param str the input String * @return a Set of String entries in the list */ @@ -1260,9 +1067,8 @@ /** * Convenience method to return a Collection as a delimited (e.g. CSV) * String. E.g. useful for toString() implementations. - * - * @param coll the Collection to display - * @param delim the delimiter to use (probably a ",") + * @param coll the Collection to display + * @param delim the delimiter to use (probably a ",") * @param prefix the String to start each element with * @param suffix the String to end each element with * @return the delimited String @@ -1285,8 +1091,7 @@ /** * Convenience method to return a Collection as a delimited (e.g. CSV) * String. E.g. useful for toString() implementations. - * - * @param coll the Collection to display + * @param coll the Collection to display * @param delim the delimiter to use (probably a ",") * @return the delimited String */ @@ -1297,7 +1102,6 @@ /** * Convenience method to return a Collection as a CSV String. * E.g. useful for toString() implementations. - * * @param coll the Collection to display * @return the delimited String */ @@ -1308,8 +1112,7 @@ /** * Convenience method to return a String array as a delimited (e.g. CSV) * String. E.g. useful for toString() implementations. - * - * @param arr the array to display + * @param arr the array to display * @param delim the delimiter to use (probably a ",") * @return the delimited String */ @@ -1333,39 +1136,12 @@ /** * Convenience method to return a String array as a CSV String. * E.g. useful for toString() implementations. - * * @param arr the array to display * @return the delimited String */ public static String arrayToCommaDelimitedString(Object[] arr) { return arrayToDelimitedString(arr, ","); } - /** - * Appends a space character (' ') if the argument is not empty, otherwise does nothing. This method - * can be thought of as "non-empty space". Using this method allows reduction of this: - *

    -     * if (sb.length != 0) {
    -     *     sb.append(' ');
    -     * }
    -     * sb.append(nextWord);
    - *

    To this:

    - *
    -     * nespace(sb).append(nextWord);
    - * - * @param sb the string builder to append a space to if non-empty - * @return the string builder argument for method chaining. - * @since 0.12.0 - */ - public static StringBuilder nespace(StringBuilder sb) { - if (sb == null) { - return null; - } - if (sb.length() != 0) { - sb.append(' '); - } - return sb; - } - } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/lang/Supplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/AeadAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/AeadRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/AeadResult.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/AssociatedDataSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/AsymmetricJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/AsymmetricJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Curve.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/DecryptAeadRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/DecryptionKeyRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/DigestAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/DigestSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/DynamicJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/EcPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/EcPrivateJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/EcPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/EcPublicJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/HashAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/InvalidKeyException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/InvalidKeyException.java (.../InvalidKeyException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/InvalidKeyException.java (.../InvalidKeyException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,30 +16,11 @@ package io.jsonwebtoken.security; /** - * A {@code KeyException} thrown when encountering a key that is not suitable for the required functionality, or - * when attempting to use a Key in an incorrect or prohibited manner. - * * @since 0.10.0 */ public class InvalidKeyException extends KeyException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public InvalidKeyException(String message) { super(message); } - - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - * @since 0.12.0 - */ - public InvalidKeyException(String message, Throwable cause) { - super(message, cause); - } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/IvSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Jwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/JwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/JwkParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/JwkSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/JwkSetBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/JwkSetParserBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/JwkThumbprint.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Jwks.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyBuilderSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyException.java (.../KeyException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyException.java (.../KeyException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,29 +16,11 @@ package io.jsonwebtoken.security; /** - * General-purpose exception when encountering a problem with a cryptographic {@link java.security.Key} - * or {@link Jwk}. - * * @since 0.10.0 */ public class KeyException extends SecurityException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public KeyException(String message) { super(message); } - - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param msg the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ - public KeyException(String msg, Throwable cause) { - super(msg, cause); - } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyLengthSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyOperation.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyOperationBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyOperationPolicied.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyOperationPolicy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyOperationPolicyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyPair.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyPairBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyPairBuilderSupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeyResult.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/KeySupplier.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Keys.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Keys.java (.../Keys.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Keys.java (.../Keys.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -15,16 +15,16 @@ */ package io.jsonwebtoken.security; -import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Classes; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.KeyPair; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.PublicKey; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Utility class for securely generating {@link SecretKey}s and {@link KeyPair}s. @@ -33,20 +33,36 @@ */ public final class Keys { - private static final String BRIDGE_CLASSNAME = "io.jsonwebtoken.impl.security.KeysBridge"; - private static final Class BRIDGE_CLASS = Classes.forName(BRIDGE_CLASSNAME); - private static final Class[] FOR_PASSWORD_ARG_TYPES = new Class[]{char[].class}; - private static final Class[] SECRET_BUILDER_ARG_TYPES = new Class[]{SecretKey.class}; - private static final Class[] PRIVATE_BUILDER_ARG_TYPES = new Class[]{PrivateKey.class}; + private static final String MAC = "io.jsonwebtoken.impl.crypto.MacProvider"; + private static final String RSA = "io.jsonwebtoken.impl.crypto.RsaProvider"; + private static final String EC = "io.jsonwebtoken.impl.crypto.EllipticCurveProvider"; - private static T invokeStatic(String method, Class[] argTypes, Object... args) { - return Classes.invokeStatic(BRIDGE_CLASS, method, argTypes, args); - } + private static final Class[] SIG_ARG_TYPES = new Class[]{SignatureAlgorithm.class}; + //purposefully ordered higher to lower: + private static final List PREFERRED_HMAC_ALGS = Collections.unmodifiableList(Arrays.asList( + SignatureAlgorithm.HS512, SignatureAlgorithm.HS384, SignatureAlgorithm.HS256)); + //prevent instantiation private Keys() { } + /* + public static final int bitLength(Key key) throws IllegalArgumentException { + Assert.notNull(key, "Key cannot be null."); + if (key instanceof SecretKey) { + byte[] encoded = key.getEncoded(); + return Arrays.length(encoded) * 8; + } else if (key instanceof RSAKey) { + return ((RSAKey)key).getModulus().bitLength(); + } else if (key instanceof ECKey) { + return ((ECKey)key).getParams().getOrder().bitLength(); + } + + throw new IllegalArgumentException("Unsupported key type: " + key.getClass().getName()); + } + */ + /** * Creates a new SecretKey instance for use with HMAC-SHA algorithms based on the specified key byte array. * @@ -64,52 +80,30 @@ int bitLength = bytes.length * 8; - //Purposefully ordered higher to lower to ensure the strongest key possible can be generated. - if (bitLength >= 512) { - return new SecretKeySpec(bytes, "HmacSHA512"); - } else if (bitLength >= 384) { - return new SecretKeySpec(bytes, "HmacSHA384"); - } else if (bitLength >= 256) { - return new SecretKeySpec(bytes, "HmacSHA256"); + for (SignatureAlgorithm alg : PREFERRED_HMAC_ALGS) { + if (bitLength >= alg.getMinKeyLength()) { + return new SecretKeySpec(bytes, alg.getJcaName()); + } } String msg = "The specified key byte array is " + bitLength + " bits which " + - "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.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."; + "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 " + Keys.class.getName() + "#secretKeyFor(SignatureAlgorithm) method " + + "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); } /** - *

    Deprecation Notice

    + * Returns a new {@link SecretKey} with a key length suitable for use with the specified {@link SignatureAlgorithm}. * - *

    As of JJWT 0.12.0, symmetric (secret) key algorithm instances can generate a key of suitable - * length for that specific algorithm by calling their {@code key()} builder method directly. For example:

    - * - *
    
    -     * {@link Jwts.SIG#HS256}.key().build();
    -     * {@link Jwts.SIG#HS384}.key().build();
    -     * {@link Jwts.SIG#HS512}.key().build();
    -     * 
    - * - *

    Call those methods as needed instead of this static {@code secretKeyFor} helper method - the returned - * {@link KeyBuilder} allows callers to specify a preferred Provider or SecureRandom on the builder if - * desired, whereas this {@code secretKeyFor} method does not. Consequently this helper method will be removed - * before the 1.0 release.

    - * - *

    Previous Documentation

    - * - *

    Returns a new {@link SecretKey} with a key length suitable for use with the specified {@link SignatureAlgorithm}.

    - * *

    JWA Specification (RFC 7518), Section 3.2 * requires minimum key lengths to be used for each respective Signature Algorithm. This method returns a * secure-random generated SecretKey that adheres to the required minimum key length. The lengths are:

    * * - * * * * @@ -130,49 +124,28 @@ * * @param alg the {@code SignatureAlgorithm} to inspect to determine which key length to use. * @return a new {@link SecretKey} instance suitable for use with the specified {@link SignatureAlgorithm}. - * @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 0.12.0. Use your preferred {@link MacAlgorithm} instance's - * {@link MacAlgorithm#key() key()} builder method directly. + * @throws IllegalArgumentException for any input value other than {@link SignatureAlgorithm#HS256}, + * {@link SignatureAlgorithm#HS384}, or {@link SignatureAlgorithm#HS512} */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - public static SecretKey secretKeyFor(io.jsonwebtoken.SignatureAlgorithm alg) throws IllegalArgumentException { + public static SecretKey secretKeyFor(SignatureAlgorithm alg) throws IllegalArgumentException { Assert.notNull(alg, "SignatureAlgorithm cannot be null."); - SecureDigestAlgorithm salg = Jwts.SIG.get().get(alg.name()); - if (!(salg instanceof MacAlgorithm)) { - String msg = "The " + alg.name() + " algorithm does not support shared secret keys."; - throw new IllegalArgumentException(msg); + switch (alg) { + case HS256: + case HS384: + case HS512: + return Classes.invokeStatic(MAC, "generateKey", SIG_ARG_TYPES, alg); + default: + String msg = "The " + alg.name() + " algorithm does not support shared secret keys."; + throw new IllegalArgumentException(msg); } - return ((MacAlgorithm) salg).key().build(); } /** - *

    Deprecation Notice

    + * Returns a new {@link KeyPair} suitable for use with the specified asymmetric algorithm. * - *

    As of JJWT 0.12.0, asymmetric key algorithm instances can generate KeyPairs of suitable strength - * for that specific algorithm by calling their {@code keyPair()} builder method directly. For example:

    - * - *
    -     * 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}.keyPair().build();
    - * - *

    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 - * desired, whereas this {@code keyPairFor} method does not. Consequently this helper method will be removed - * before the 1.0 release.

    - * - *

    Previous Documentation

    - * - *

    Returns a new {@link KeyPair} suitable for use with the specified asymmetric algorithm.

    - * *

    If the {@code alg} argument is an RSA algorithm, a KeyPair is generated based on the following:

    * *
    JWA HMAC-SHA Key Length Requirements
    AlgorithmKey Length
    - * * * * @@ -206,28 +179,27 @@ *

    If the {@code alg} argument is an Elliptic Curve algorithm, a KeyPair is generated based on the following:

    * *
    Generated RSA Key Sizes
    JWA AlgorithmKey Size
    - * * * * * * * * - * + * * * * * * - * + * * * * * * - * - * + * + * * * * @@ -236,97 +208,24 @@ * @param alg the {@code SignatureAlgorithm} to inspect to determine which asymmetric algorithm to use. * @return a new {@link KeyPair} suitable for use with the specified asymmetric algorithm. * @throws IllegalArgumentException if {@code alg} is not an asymmetric algorithm - * @deprecated since 0.12.0 in favor of your preferred - * {@link io.jsonwebtoken.security.SignatureAlgorithm} instance's - * {@link SignatureAlgorithm#keyPair() keyPair()} builder method directly. */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - public static KeyPair keyPairFor(io.jsonwebtoken.SignatureAlgorithm alg) throws IllegalArgumentException { + public static KeyPair keyPairFor(SignatureAlgorithm alg) throws IllegalArgumentException { Assert.notNull(alg, "SignatureAlgorithm cannot be null."); - SecureDigestAlgorithm salg = Jwts.SIG.get().get(alg.name()); - if (!(salg instanceof SignatureAlgorithm)) { - String msg = "The " + alg.name() + " algorithm does not support Key Pairs."; - throw new IllegalArgumentException(msg); + switch (alg) { + case RS256: + case PS256: + case RS384: + case PS384: + case RS512: + case PS512: + return Classes.invokeStatic(RSA, "generateKeyPair", SIG_ARG_TYPES, alg); + case ES256: + case ES384: + case ES512: + return Classes.invokeStatic(EC, "generateKeyPair", SIG_ARG_TYPES, alg); + default: + String msg = "The " + alg.name() + " algorithm does not support Key Pairs."; + throw new IllegalArgumentException(msg); } - SignatureAlgorithm asalg = ((SignatureAlgorithm) salg); - return asalg.keyPair().build(); } - - /** - * Returns a new {@link Password} instance suitable for use with password-based key derivation algorithms. - * - *

    Usage Note: Using {@code Password}s outside of key derivation contexts will likely - * fail. See the {@link Password} JavaDoc for more, and also note the Password Safety section below.

    - * - *

    Password Safety

    - * - *

    Instances returned by this method use a clone of the specified {@code password} character array - * argument - changes to the argument array will NOT be reflected in the returned key, and vice versa. If you wish - * to clear a {@code Password} instance to ensure it is no longer usable, call its {@link Password#destroy()} - * method will clear/overwrite its internal cloned char array. Also note that each subsequent call to - * {@link Password#toCharArray()} will also return a new clone of the underlying password character array per - * standard JCE key behavior.

    - * - * @param password the raw password character array to clone for use with password-based key derivation algorithms. - * @return a new {@link Password} instance that wraps a new clone of the specified {@code password} character array. - * @see Password#toCharArray() - * @since 0.12.0 - */ - public static Password password(char[] password) { - return invokeStatic("password", FOR_PASSWORD_ARG_TYPES, new Object[]{password}); - } - - /** - * Returns a {@code SecretKeyBuilder} that produces the specified key, allowing association with a - * {@link SecretKeyBuilder#provider(Provider) provider} that must be used with the key during cryptographic - * operations. For example: - * - *
    -     * SecretKey key = Keys.builder(key).provider(mandatoryProvider).build();
    - * - *

    Cryptographic algorithm implementations can inspect the resulting {@code key} instance and obtain its - * mandatory {@code Provider} if necessary.

    - * - *

    This method is primarily only useful for keys that cannot expose key material, such as PKCS11 or HSM - * (Hardware Security Module) keys, and require a specific {@code Provider} to be used during cryptographic - * operations.

    - * - * @param key the secret key to use for cryptographic operations, potentially associated with a configured - * {@link Provider} - * @return a new {@code SecretKeyBuilder} that produces the specified key, potentially associated with any - * specified provider. - * @since 0.12.0 - */ - public static SecretKeyBuilder builder(SecretKey key) { - Assert.notNull(key, "SecretKey cannot be null."); - return invokeStatic("builder", SECRET_BUILDER_ARG_TYPES, key); - } - - /** - * Returns a {@code PrivateKeyBuilder} that produces the specified key, allowing association with a - * {@link PrivateKeyBuilder#publicKey(PublicKey) publicKey} to obtain public key data if necessary, or a - * {@link SecretKeyBuilder#provider(Provider) provider} that must be used with the key during cryptographic - * operations. For example: - * - *
    -     * PrivateKey key = Keys.builder(privateKey).publicKey(publicKey).provider(mandatoryProvider).build();
    - * - *

    Cryptographic algorithm implementations can inspect the resulting {@code key} instance and obtain its - * mandatory {@code Provider} or {@code PublicKey} if necessary.

    - * - *

    This method is primarily only useful for keys that cannot expose key material, such as PKCS11 or HSM - * (Hardware Security Module) keys, and require a specific {@code Provider} or public key data to be used - * during cryptographic operations.

    - * - * @param key the private key to use for cryptographic operations, potentially associated with a configured - * {@link Provider} or {@link PublicKey}. - * @return a new {@code PrivateKeyBuilder} that produces the specified private key, potentially associated with any - * specified provider or {@code PublicKey} - * @since 0.12.0 - */ - public static PrivateKeyBuilder builder(PrivateKey key) { - Assert.notNull(key, "PrivateKey cannot be null."); - return invokeStatic("builder", PRIVATE_BUILDER_ARG_TYPES, key); - } } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/MacAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/MalformedKeyException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/MalformedKeySetException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Message.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/OctetPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/OctetPrivateJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/OctetPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/OctetPublicJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Password.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/PrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/PrivateJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/PrivateKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/PublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/PublicJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/Request.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/RsaPrivateJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/RsaPrivateJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/RsaPublicJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/RsaPublicJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecretJwk.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecretJwkBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecretKeyAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecretKeyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecureDigestAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecureRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecurityBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecurityException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecurityException.java (.../SecurityException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SecurityException.java (.../SecurityException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -18,28 +18,14 @@ import io.jsonwebtoken.JwtException; /** - * A {@code JwtException} attributed to a problem with security-related elements, such as - * cryptographic keys, algorithms, or the underlying Java JCA API. - * * @since 0.10.0 */ public class SecurityException extends JwtException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public SecurityException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public SecurityException(String message, Throwable cause) { super(message, cause); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SignatureAlgorithm.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SignatureException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SignatureException.java (.../SignatureException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/SignatureException.java (.../SignatureException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,28 +16,14 @@ package io.jsonwebtoken.security; /** - * Exception thrown if there is problem calculating or verifying a digital signature or message authentication code. - * * @since 0.10.0 */ -@SuppressWarnings("deprecation") public class SignatureException extends io.jsonwebtoken.SignatureException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public SignatureException(String message) { super(message); } - /** - * Creates a new instance with the specified explanation message and underlying cause. - * - * @param message the message explaining why the exception is thrown. - * @param cause the underlying cause that resulted in this exception being thrown. - */ public SignatureException(String message, Throwable cause) { super(message, cause); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/UnsupportedKeyException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/VerifyDigestRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/VerifySecureDigestRequest.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/WeakKeyException.java =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/WeakKeyException.java (.../WeakKeyException.java) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ 3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/WeakKeyException.java (.../WeakKeyException.java) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -16,18 +16,10 @@ package io.jsonwebtoken.security; /** - * Exception thrown when encountering a key that is not strong enough (of sufficient length) to be used with - * a particular algorithm or in a particular security context. - * * @since 0.10.0 */ public class WeakKeyException extends InvalidKeyException { - /** - * Creates a new instance with the specified explanation message. - * - * @param message the message explaining why the exception is thrown. - */ public WeakKeyException(String message) { super(message); } Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/X509Accessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/X509Builder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b673aa90094faa6f77a76c311d738710d7cf323a refers to a dead (removed) revision in file `3rdParty_sources/jsonwebtoken/io/jsonwebtoken/security/X509Mutator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: idea_project/.idea/libraries/3rdParty.xml =================================================================== diff -u -r683b1a0cbc595fe30e200900d081c88105aae63c -rb673aa90094faa6f77a76c311d738710d7cf323a --- idea_project/.idea/libraries/3rdParty.xml (.../3rdParty.xml) (revision 683b1a0cbc595fe30e200900d081c88105aae63c) +++ idea_project/.idea/libraries/3rdParty.xml (.../3rdParty.xml) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -51,17 +51,18 @@ - - - + + + + \ No newline at end of file Index: lams_build/lib/json/jjwt-api-0.11.2.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jjwt-api-0.12.5.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jjwt-impl-0.11.2.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jjwt-impl-0.12.5.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jjwt-jackson-0.11.2.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jjwt-jackson-0.12.5.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jjwt.module.xml =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a --- lams_build/lib/json/jjwt.module.xml (.../jjwt.module.xml) (revision ca3e06f3b65d2880d69fd5278773c5c71e1ca3e7) +++ lams_build/lib/json/jjwt.module.xml (.../jjwt.module.xml) (revision b673aa90094faa6f77a76c311d738710d7cf323a) @@ -24,10 +24,10 @@ - - - - + + + + Index: lams_build/lib/json/jwks-rsa-0.20.0.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ Index: lams_build/lib/json/jwks-rsa-0.22.1.jar =================================================================== diff -u -rca3e06f3b65d2880d69fd5278773c5c71e1ca3e7 -rb673aa90094faa6f77a76c311d738710d7cf323a Binary files differ
    Generated Elliptic Curve Key Parameters
    JWA AlgorithmKey SizeJWA Curve NameASN1 OID Curve Name
    ES256EC256256 bits{@code P-256}{@code secp256r1}
    ES384EC384384 bits{@code P-384}{@code secp384r1}
    ES512521 bitsEC512512 bits{@code P-521}{@code secp521r1}