diff --git a/.travis.yml b/.travis.yml index 197d2a00..5b8836e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,19 @@ # https://travis-ci.org/jwtk/jjwt -language: java +dist: trusty +sudo: required +language: java jdk: - - oraclejdk7 + - openjdk7 - oraclejdk8 before_install: - export BUILD_COVERAGE="$([ $TRAVIS_JDK_VERSION == 'oraclejdk8' ] && echo 'true')" + install: echo "No need to run mvn install -DskipTests then mvn install. Running mvn install." + script: mvn install + after_success: - test -z "$BUILD_COVERAGE" || mvn clean test jacoco:report coveralls:report + diff --git a/README.md b/README.md index 10d0e128..1984b3cf 100644 --- a/README.md +++ b/README.md @@ -193,9 +193,9 @@ try { // we get here if the required claim is not present - } catch (IncorrectClaimException) { + } catch (IncorrectClaimException e) { - // we get here if ther required claim has the wrong value + // we get here if the required claim has the wrong value } ``` diff --git a/pom.xml b/pom.xml index f62505fa..0202977e 100644 --- a/pom.xml +++ b/pom.xml @@ -55,23 +55,23 @@ 3.0.2 - 3.5.1 + 3.6.1 1.6 UTF-8 ${user.name}-${maven.build.timestamp} - 2.8.2 + 2.8.9 - 1.55 + 1.56 - 2.4.7 - 1.1.7 + 2.4.11 + 1.2.3 3.4 4.12 - 1.6.5 + 1.6.6 2.19.1 @@ -159,7 +159,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 1.3.1 + 1.4.1 enforce-banned-dependencies @@ -247,7 +247,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.17 + 2.20 **/*IT.java @@ -272,7 +272,7 @@ org.jacoco jacoco-maven-plugin - 0.7.6.201602180812 + 0.7.9 **/io/jsonwebtoken/lang/* @@ -290,12 +290,12 @@ org.apache.maven.plugins maven-release-plugin - 2.5 + 2.5.3 org.apache.maven.scm maven-scm-provider-gitexe - 1.9 + 1.9.5 @@ -308,7 +308,7 @@ org.apache.felix maven-bundle-plugin - 3.0.1 + 3.3.0 true @@ -334,7 +334,7 @@ org.eluder.coveralls coveralls-maven-plugin - 4.0.0 + 4.3.0 @@ -356,7 +356,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.5 + 1.6 sign-artifacts @@ -377,7 +377,7 @@ org.apache.maven.plugins maven-source-plugin - 2.3 + 3.0.1 attach-sources @@ -390,7 +390,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 + 2.10.4 attach-javadocs diff --git a/src/main/java/io/jsonwebtoken/Header.java b/src/main/java/io/jsonwebtoken/Header.java index ba6b850c..1d8ab9af 100644 --- a/src/main/java/io/jsonwebtoken/Header.java +++ b/src/main/java/io/jsonwebtoken/Header.java @@ -115,11 +115,11 @@ public interface Header> extends Map { * *
Compatiblity 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. Compression when - * creating JWE tokens however should be universally accepted for any library that supports JWE.

+ *

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 @@ -133,13 +133,14 @@ public interface Header> extends Map { * *
Compatiblity 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. Compression when - * creating JWE tokens however should be universally accepted for any library that supports JWE.

+ *

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.

* - * @param zip the JWT compression algorithm {@code zip} value or {@code null} to remove the property from the JSON map. + * @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); diff --git a/src/main/java/io/jsonwebtoken/JwtBuilder.java b/src/main/java/io/jsonwebtoken/JwtBuilder.java index 998e832d..782352f0 100644 --- a/src/main/java/io/jsonwebtoken/JwtBuilder.java +++ b/src/main/java/io/jsonwebtoken/JwtBuilder.java @@ -101,6 +101,18 @@ public interface JwtBuilder extends ClaimsMutator { */ JwtBuilder setClaims(Map claims); + /** + * Adds all given name/value pairs to the JSON Claims in the payload. If a Claims instance does not yet exist at the + * time this method is called, one will be created automatically before applying the name/value pairs. + * + *

The payload 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 body. + * @return the builder for method chaining. + * @since 0.8 + */ + JwtBuilder addClaims(Map claims); + /** * Sets the JWT Claims * iss (issuer) value. A {@code null} value will remove the property from the Claims. @@ -358,10 +370,10 @@ public interface JwtBuilder extends ClaimsMutator { * *
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 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 diff --git a/src/main/java/io/jsonwebtoken/JwtParser.java b/src/main/java/io/jsonwebtoken/JwtParser.java index fd1f6c7e..c0fa1603 100644 --- a/src/main/java/io/jsonwebtoken/JwtParser.java +++ b/src/main/java/io/jsonwebtoken/JwtParser.java @@ -187,9 +187,6 @@ public interface JwtParser { * (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[])}.

* * @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital * signature. diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java b/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java index 76d3a2c3..25b48d62 100644 --- a/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java +++ b/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java @@ -17,14 +17,7 @@ package io.jsonwebtoken.impl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.CompressionCodec; -import io.jsonwebtoken.Header; -import io.jsonwebtoken.JwsHeader; -import io.jsonwebtoken.JwtBuilder; -import io.jsonwebtoken.JwtParser; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.*; import io.jsonwebtoken.impl.crypto.DefaultJwtSigner; import io.jsonwebtoken.impl.crypto.JwtSigner; import io.jsonwebtoken.lang.Assert; @@ -148,6 +141,12 @@ public class DefaultJwtBuilder implements JwtBuilder { return this; } + @Override + public JwtBuilder addClaims(Map claims) { + ensureClaims().putAll(claims); + return this; + } + @Override public JwtBuilder setIssuer(String iss) { if (Strings.hasText(iss)) { diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java b/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java index 14913f18..90a80a83 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java +++ b/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java @@ -19,6 +19,7 @@ import java.security.InvalidKeyException; import java.security.Key; import java.security.PrivateKey; import java.security.Signature; +import java.security.interfaces.ECKey; import java.security.interfaces.ECPrivateKey; import io.jsonwebtoken.JwtException; @@ -29,9 +30,9 @@ public class EllipticCurveSigner extends EllipticCurveProvider implements Signer public EllipticCurveSigner(SignatureAlgorithm alg, Key key) { super(alg, key); - if (!(key instanceof ECPrivateKey)) { - String msg = "Elliptic Curve signatures must be computed using an ECPrivateKey. The specified key of " + - "type " + key.getClass().getName() + " is not an ECPrivateKey."; + if (!(key instanceof PrivateKey && key instanceof ECKey)) { + String msg = "Elliptic Curve signatures must be computed using an EC PrivateKey. The specified key of " + + "type " + key.getClass().getName() + " is not an EC PrivateKey."; throw new IllegalArgumentException(msg); } } diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy b/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy index e4c6cdbe..f4a87fc3 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy +++ b/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy @@ -74,6 +74,26 @@ class DefaultJwtBuilderTest { assertSame b.claims, c } + @Test + void testAddClaims() { + def b = new DefaultJwtBuilder() + def c = Jwts.claims([initial: 'initial']) + b.setClaims(c) + def c2 = [foo: 'bar', baz: 'buz'] + b.addClaims(c2) + assertEquals 'initial', b.claims.get('initial') + assertEquals 'bar', b.claims.get('foo') + } + + @Test + void testAddClaimsWithoutInitializing() { + def b = new DefaultJwtBuilder() + def c = [foo: 'bar', baz: 'buz'] + b.addClaims(c) + assertNotNull b.claims + assertEquals b.claims, c + } + @Test void testClaim() { def b = new DefaultJwtBuilder() diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy b/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy index 02067309..d4e4b395 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy +++ b/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy @@ -46,8 +46,8 @@ class EllipticCurveSignerTest { new EllipticCurveSigner(SignatureAlgorithm.ES256, key); fail('EllipticCurveSigner should reject non ECPrivateKey instances.') } catch (IllegalArgumentException expected) { - assertEquals expected.message, "Elliptic Curve signatures must be computed using an ECPrivateKey. The specified key of " + - "type " + key.getClass().getName() + " is not an ECPrivateKey."; + assertEquals expected.message, "Elliptic Curve signatures must be computed using an EC PrivateKey. The specified key of " + + "type " + key.getClass().getName() + " is not an EC PrivateKey."; } }