mirror of https://github.com/jwtk/jjwt.git
113: javadoc cleanup, compression backwards compatibility change
This commit is contained in:
parent
fbce510164
commit
c62d012cf8
|
@ -25,9 +25,11 @@ package io.jsonwebtoken;
|
|||
public interface CompressionCodec {
|
||||
|
||||
/**
|
||||
* The algorithm name to use as the JWT's {@code calg} header value.
|
||||
* The algorithm name to use as the JWT's
|
||||
* <a href="https://tools.ietf.org/html/rfc7516#section-4.1.3"><code>zip</code></a> header value.
|
||||
*
|
||||
* @return the algorithm name to use as the JWT's {@code calg} header value.
|
||||
* @return the algorithm name to use as the JWT's
|
||||
* <a href="https://tools.ietf.org/html/rfc7516#section-4.1.3"><code>zip</code></a> header value.
|
||||
*/
|
||||
String getAlgorithmName();
|
||||
|
||||
|
|
|
@ -48,8 +48,12 @@ public interface Header<T extends Header<T>> extends Map<String,Object> {
|
|||
/** JWT {@code Content Type} header parameter name: <code>"cty"</code> */
|
||||
public static final String CONTENT_TYPE = "cty";
|
||||
|
||||
/** JWT {@code Compression Algorithm} header parameter name: <code>"calg"</code> */
|
||||
public static final String COMPRESSION_ALGORITHM = "calg";
|
||||
/** JWT {@code Compression Algorithm} header parameter name: <code>"zip"</code> */
|
||||
public static final String COMPRESSION_ALGORITHM = "zip";
|
||||
|
||||
/** JJWT legacy/deprecated {@code Compression Algorithm} header parameter names <code>"calg"</code>
|
||||
* @deprecated use {@link #COMPRESSION_ALGORITHM} instead. */
|
||||
public static final String DEPRECATED_COMPRESSION_ALGORITHM = "calg";
|
||||
|
||||
/**
|
||||
* Returns the <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-5.1">
|
||||
|
@ -104,24 +108,38 @@ public interface Header<T extends Header<T>> extends Map<String,Object> {
|
|||
T setContentType(String cty);
|
||||
|
||||
/**
|
||||
* Returns the JWT <code>calg</code> (Compression Algorithm) header value or {@code null} if not present.
|
||||
* Returns the JWT <a href="https://tools.ietf.org/html/rfc7516#section-4.1.3"><code>zip</code></a>
|
||||
* (Compression Algorithm) header parameter value or {@code null} if not present.
|
||||
*
|
||||
* @return the {@code calg} header parameter value or {@code null} if not present.
|
||||
* <h5>Compatiblity Note</h5>
|
||||
*
|
||||
* <p>While the JWT family of specifications only defines the <code>zip</code> header in the JWE (Json Web Encryption)
|
||||
* specification, JJWT will also support compression for JWS as well if you choose to use it. However,
|
||||
* be aware that <b>if you use
|
||||
* compression when creating a JWS token, other libraries may not be able to parse the JWS</b>. Compression when
|
||||
* creating JWE tokens however should be universally accepted for any library that supports JWE.</p>
|
||||
*
|
||||
* @return the {@code zip} header parameter value or {@code null} if not present.
|
||||
* @since 0.6.0
|
||||
*/
|
||||
String getCompressionAlgorithm();
|
||||
|
||||
/**
|
||||
* Sets the JWT <code>calg</code> (Compression Algorithm) header parameter value. A {@code null} value will remove
|
||||
* Sets the JWT <a href="https://tools.ietf.org/html/rfc7516#section-4.1.3"><code>zip</code></a>
|
||||
* (Compression Algorithm) header parameter value. A {@code null} value will remove
|
||||
* the property from the JSON map.
|
||||
* <p>
|
||||
* <p>The compression algorithm is NOT part of the <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25>JWT specification</a>
|
||||
* 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. </p>
|
||||
*
|
||||
* @param calg the JWT compression algorithm {@code calg} value or {@code null} to remove the property from the JSON map.
|
||||
* <h5>Compatiblity Note</h5>
|
||||
*
|
||||
* <p>While the JWT family of specifications only defines the <code>zip</code> header in the JWE (Json Web Encryption)
|
||||
* specification, JJWT will also support compression for JWS as well if you choose to use it. However,
|
||||
* be aware that <b>if you use
|
||||
* compression when creating a JWS token, other libraries may not be able to parse the JWS</b>. Compression when
|
||||
* creating JWE tokens however should be universally accepted for any library that supports JWE.</p>
|
||||
*
|
||||
* @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 calg);
|
||||
T setCompressionAlgorithm(String zip);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package io.jsonwebtoken;
|
||||
|
||||
/**
|
||||
* A <a href="https://tools.ietf.org/html/rfc7516">JWE</a> header.
|
||||
*
|
||||
* @param <T> header type
|
||||
* @since 0.7.0
|
||||
*/
|
||||
public interface JweHeader<T extends JweHeader<T>> extends Header<T> {
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.1">Algorithm Header</a> name: the string literal <b><code>alg</code></b>
|
||||
*/
|
||||
public static final String ALGORITHM = "alg";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.2">Encryption Algorithm Header</a> name: the string literal <b><code>enc</code></b>
|
||||
*/
|
||||
public static final String ENCRYPTION_ALGORITHM = "enc";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.3">Compression Algorithm Header</a> name: the string literal <b><code>zip</code></b>
|
||||
*/
|
||||
public static final String COMPRESSION_ALGORITHM = "zip";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.4">JWK Set URL Header</a> name: the string literal <b><code>jku</code></b>
|
||||
*/
|
||||
public static final String JWK_SET_URL = "jku";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.5">JSON Web Key Header</a> name: the string literal <b><code>jwk</code></b>
|
||||
*/
|
||||
public static final String JSON_WEB_KEY = "jwk";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.6">Key ID Header</a> name: the string literal <b><code>kid</code></b>
|
||||
*/
|
||||
public static final String KEY_ID = "kid";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.7">X.509 URL Header</a> name: the string literal <b><code>x5u</code></b>
|
||||
*/
|
||||
public static final String X509_URL = "x5u";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.8">X.509 Certificate Chain Header</a> name: the string literal <b><code>x5c</code></b>
|
||||
*/
|
||||
public static final String X509_CERT_CHAIN = "x5c";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.9">X.509 Certificate SHA-1 Thumbprint Header</a> name: the string literal <b><code>x5t</code></b>
|
||||
*/
|
||||
public static final String X509_CERT_SHA1_THUMBPRINT = "x5t";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.10">X.509 Certificate SHA-256 Thumbprint Header</a> name: the string literal <b><code>x5t#S256</code></b>
|
||||
*/
|
||||
public static final String X509_CERT_SHA256_THUMBPRINT = "x5t#S256";
|
||||
|
||||
/**
|
||||
* JWE <a href="https://tools.ietf.org/html/rfc7516#section-4.1.13">Critical Header</a> name: the string literal <b><code>crit</code></b>
|
||||
*/
|
||||
public static final String CRITICAL = "crit";
|
||||
|
||||
}
|
|
@ -16,44 +16,61 @@
|
|||
package io.jsonwebtoken;
|
||||
|
||||
/**
|
||||
* A <a href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31">JWS</a> header.
|
||||
* A <a href="https://tools.ietf.org/html/rfc7515">JWS</a> header.
|
||||
*
|
||||
* @param <T> header type
|
||||
* @since 0.1
|
||||
*/
|
||||
public interface JwsHeader<T extends JwsHeader<T>> extends Header<T> {
|
||||
|
||||
/** JWS {@code Algorithm} header parameter name: <code>"alg"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">Algorithm Header</a> name: the string literal <b><code>alg</code></b>
|
||||
*/
|
||||
public static final String ALGORITHM = "alg";
|
||||
|
||||
/** JWS {@code JWT Set URL} header parameter name: <code>"jku"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.2">JWK Set URL Header</a> name: the string literal <b><code>jku</code></b>
|
||||
*/
|
||||
public static final String JWK_SET_URL = "jku";
|
||||
|
||||
/** JWS {@code JSON Web Key} header parameter name: <code>"jwk"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.3">JSON Web Key Header</a> name: the string literal <b><code>jwk</code></b>
|
||||
*/
|
||||
public static final String JSON_WEB_KEY = "jwk";
|
||||
|
||||
/** JWS {@code Key ID} header parameter name: <code>"kid"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.4">Key ID Header</a> name: the string literal <b><code>kid</code></b>
|
||||
*/
|
||||
public static final String KEY_ID = "kid";
|
||||
|
||||
/** JWS {@code X.509 URL} header parameter name: <code>"x5u"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.5">X.509 URL Header</a> name: the string literal <b><code>x5u</code></b>
|
||||
*/
|
||||
public static final String X509_URL = "x5u";
|
||||
|
||||
/** JWS {@code X.509 Certificate Chain} header parameter name: <code>"x5c"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.6">X.509 Certificate Chain Header</a> name: the string literal <b><code>x5c</code></b>
|
||||
*/
|
||||
public static final String X509_CERT_CHAIN = "x5c";
|
||||
|
||||
/** JWS {@code X.509 Certificate SHA-1 Thumbprint} header parameter name: <code>"x5t"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.7">X.509 Certificate SHA-1 Thumbprint Header</a> name: the string literal <b><code>x5t</code></b>
|
||||
*/
|
||||
public static final String X509_CERT_SHA1_THUMBPRINT = "x5t";
|
||||
|
||||
/** JWS {@code X.509 Certificate SHA-256 Thumbprint} header parameter name: <code>"x5t#S256"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.8">X.509 Certificate SHA-256 Thumbprint Header</a> name: the string literal <b><code>x5t#S256</code></b>
|
||||
*/
|
||||
public static final String X509_CERT_SHA256_THUMBPRINT = "x5t#S256";
|
||||
|
||||
/** JWS {@code Critical} header parameter name: <code>"crit"</code> */
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.11">Critical Header</a> name: the string literal <b><code>crit</code></b>
|
||||
*/
|
||||
public static final String CRITICAL = "crit";
|
||||
|
||||
/**
|
||||
* Returns the JWS <a href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-4.1.1">
|
||||
* Returns the JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">
|
||||
* <code>alg</code></a> (algorithm) header value or {@code null} if not present.
|
||||
*
|
||||
* <p>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.</p>
|
||||
|
@ -64,9 +81,8 @@ public interface JwsHeader<T extends JwsHeader<T>> extends Header<T> {
|
|||
String getAlgorithm();
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-4.1.1">
|
||||
* Sets the JWT <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">
|
||||
* <code>alg</code></a> (Algorithm) header value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* <p>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.</p>
|
||||
|
@ -77,13 +93,11 @@ public interface JwsHeader<T extends JwsHeader<T>> extends Header<T> {
|
|||
T setAlgorithm(String alg);
|
||||
|
||||
/**
|
||||
* Returns the JWS <a href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-4.1.4">
|
||||
* Returns the JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.4">
|
||||
* <code>kid</code></a> (Key ID) header value or {@code null} if not present.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>When used with a JWK, the keyId value is used to match a JWK {@code keyId} parameter value.</p>
|
||||
*
|
||||
* @return the JWS {@code kid} header value or {@code null} if not present.
|
||||
|
@ -91,13 +105,11 @@ public interface JwsHeader<T extends JwsHeader<T>> extends Header<T> {
|
|||
String getKeyId();
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-4.1.4">
|
||||
* Sets the JWT <a href="https://tools.ietf.org/html/rfc7516#section-4.1.4">
|
||||
* <code>kid</code></a> (Key ID) header value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>When used with a JWK, the keyId value is used to match a JWK {@code keyId} parameter value.</p>
|
||||
*
|
||||
* @param kid the JWS {@code kid} header value or {@code null} to remove the property from the JSON map.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package io.jsonwebtoken.impl;
|
||||
|
||||
import io.jsonwebtoken.Header;
|
||||
import io.jsonwebtoken.lang.Strings;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -52,9 +53,15 @@ public class DefaultHeader<T extends Header<T>> extends JwtMap implements Header
|
|||
return (T)this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public String getCompressionAlgorithm() {
|
||||
return getString(COMPRESSION_ALGORITHM);
|
||||
String s = getString(COMPRESSION_ALGORITHM);
|
||||
if (!Strings.hasText(s)) {
|
||||
//backwards compatibility TODO: remove when releasing 1.0
|
||||
s = getString(DEPRECATED_COMPRESSION_ALGORITHM);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,6 @@ import io.jsonwebtoken.impl.compression.GzipCompressionCodec
|
|||
import io.jsonwebtoken.impl.crypto.EllipticCurveProvider
|
||||
import io.jsonwebtoken.impl.crypto.MacProvider
|
||||
import io.jsonwebtoken.impl.crypto.RsaProvider
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import org.junit.Test
|
||||
|
||||
import javax.crypto.Mac
|
||||
|
@ -106,7 +105,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParsePlaintextToken() {
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true]
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
|
||||
|
@ -194,7 +193,6 @@ class JwtsTest {
|
|||
@Test
|
||||
void testWithInvalidCompressionAlgorithm() {
|
||||
try {
|
||||
|
||||
Jwts.builder().setHeaderParam(Header.COMPRESSION_ALGORITHM, "CUSTOM").setId("andId").compact()
|
||||
} catch (CompressionException e) {
|
||||
assertEquals "Unsupported compression algorithm 'CUSTOM'", e.getMessage()
|
||||
|
@ -433,6 +431,7 @@ class JwtsTest {
|
|||
assertEquals "hello this is an amazing jwt", claims.state
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = CompressionException.class)
|
||||
void testCompressedJwtWithUnrecognizedHeader() {
|
||||
byte[] key = MacProvider.generateKey().getEncoded()
|
||||
|
@ -583,7 +582,7 @@ class JwtsTest {
|
|||
|
||||
//Now strip off the signature so we can add it back in later on a forged token:
|
||||
int i = compact.lastIndexOf('.');
|
||||
String signature = compact.substring(i+1);
|
||||
String signature = compact.substring(i + 1);
|
||||
|
||||
//now let's create a fake header and payload with whatever we want (without signing):
|
||||
String forged = Jwts.builder().setSubject("Not Joe").compact();
|
||||
|
@ -702,13 +701,13 @@ class JwtsTest {
|
|||
}
|
||||
}
|
||||
|
||||
static void testRsa(SignatureAlgorithm alg, int keySize=1024, boolean verifyWithPrivateKey=false) {
|
||||
static void testRsa(SignatureAlgorithm alg, int keySize = 1024, boolean verifyWithPrivateKey = false) {
|
||||
|
||||
KeyPair kp = RsaProvider.generateKeyPair(keySize)
|
||||
PublicKey publicKey = kp.getPublic();
|
||||
PrivateKey privateKey = kp.getPrivate();
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true]
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(alg, privateKey).compact();
|
||||
|
||||
|
@ -728,7 +727,7 @@ class JwtsTest {
|
|||
//create random signing key for testing:
|
||||
byte[] key = MacProvider.generateKey().encoded
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true]
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(alg, key).compact();
|
||||
|
||||
|
@ -739,13 +738,13 @@ class JwtsTest {
|
|||
assert token.body == claims
|
||||
}
|
||||
|
||||
static void testEC(SignatureAlgorithm alg, boolean verifyWithPrivateKey=false) {
|
||||
static void testEC(SignatureAlgorithm alg, boolean verifyWithPrivateKey = false) {
|
||||
|
||||
KeyPair pair = EllipticCurveProvider.generateKeyPair(alg)
|
||||
PublicKey publicKey = pair.getPublic()
|
||||
PrivateKey privateKey = pair.getPrivate()
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true]
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(alg, privateKey).compact();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package io.jsonwebtoken.impl
|
||||
|
||||
import io.jsonwebtoken.Header
|
||||
import org.junit.Test
|
||||
import static org.junit.Assert.*
|
||||
|
||||
|
@ -37,4 +38,11 @@ class DefaultHeaderTest {
|
|||
h.setContentType('bar')
|
||||
assertEquals h.getContentType(), 'bar'
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBackwardsCompatibleCompressionHeader() {
|
||||
def h = new DefaultHeader()
|
||||
h.put(Header.DEPRECATED_COMPRESSION_ALGORITHM, "DEF")
|
||||
assertEquals "DEF", h.getCompressionAlgorithm()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue