JwtParser.parse* method renames (#845)

* Closes #834

- Deprecated JwtParser parseContentJwt, parseClaimsJwt, parseContentJws and parseClaimsJws in favor of parseUnprotectedContent, parseUnprotectedClaims, parseSignedContent, and parseSignedClaims

- Renamed the not-yet-released JwtParser parseContentJwe and parseClaimsJwe to parseEncryptedContent and parseEncryptedClaims

- Renamed the not-yet-released JwtParser overloaded unencoded payload parseContentJws and parseClaimsJws methods to parseSignedContent and parseSignedClaims

- Deprecated JwtHandler and JwtHandlerAdapter in favor of JwtVisitor and SupportedJwtVisitor
This commit is contained in:
lhazlewood 2023-10-03 10:40:06 -07:00 committed by GitHub
parent 3b529ac640
commit e78f3f511f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 1077 additions and 637 deletions

View File

@ -44,7 +44,7 @@ AeadAlgorithm enc = Jwts.ENC.A256GCM;
SecretKey key = enc.key().build();
String compact = Jwts.builder().setSubject("Joe").encryptWith(key, enc).compact();
Jwe<Claims> jwe = Jwts.parser().decryptWith(key).build().parseClaimsJwe(compact);
Jwe<Claims> jwe = Jwts.parser().decryptWith(key).build().parseEncryptedClaims(compact);
```
Many other RSA and Elliptic Curve examples are in the full README documentation.
@ -137,6 +137,11 @@ deprecate some concepts, or in some cases, completely break backwards compatibil
support expected congruent behavior with `Jwe` instances (both have digests).
* `io.jsonwebtoken.JwtParser`'s `parseContentJwt`, `parseClaimsJwt`, `parseContentJws`, and `parseClaimsJws` methods
have been deprecated in favor of more intuitive respective `parseUnsecuredContent`, `parseUnsecuredClaims`,
`parseSignedContent` and `parseSignedClaims` methods.
* `io.jsonwebtoken.CompressionCodec` is now deprecated in favor of the new `io.jsonwebtoken.io.CompressionAlgorithm`
interface. This is to guarantee API congruence with all other JWT-identifiable algorithm IDs that can be set as a
header value.

102
README.md
View File

@ -1,4 +1,4 @@
[![Build Status](https://github.com/jwtk/jjwt/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/jwtk/jjwt/actions/workflows/ci.yml?query=branch%3Amaster)
\[![Build Status](https://github.com/jwtk/jjwt/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/jwtk/jjwt/actions/workflows/ci.yml?query=branch%3Amaster)
[![Coverage Status](https://coveralls.io/repos/github/jwtk/jjwt/badge.svg?branch=master)](https://coveralls.io/github/jwtk/jjwt?branch=master)
[![Vuln score](https://snyk-widget.herokuapp.com/badge/mvn/io.jsonwebtoken/jjwt-root/badge.svg)](https://snyk-widget.herokuapp.com/badge/mvn/io.jsonwebtoken/jjwt-root/badge.svg)
[![Known Vulns](https://snyk.io/test/github/jwtk/jjwt/badge.svg)](https://snyk.io/test/github/jwtk/jjwt/badge.svg)
@ -720,7 +720,7 @@ eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.1KP0SsvENi7Uz1oQc07aXTL7kpQG5jBNIybqr60A
Now let's verify the JWT (you should always discard JWTs that don't match an expected signature):
```java
assert Jwts.parser().verifyWith(key).build().parseClaimsJws(jws).getPayload().getSubject().equals("Joe");
assert Jwts.parser().verifyWith(key).build().parseSignedClaims(jws).getPayload().getSubject().equals("Joe");
```
There are two things going on here. The `key` from before is being used to verify the signature of the JWT. If it
@ -730,7 +730,7 @@ that pack a punch!
> **Note**
>
> **Type-safe JWTs:** To get a type-safe `Claims` JWT result, call the `parseClaimsJws` method (since there are many
> **Type-safe JWTs:** To get a type-safe `Claims` JWT result, call the `parseSignedClaims` method (since there are many
similar methods available). You will get an `UnsupportedJwtException` if you parse your JWT with wrong method.
But what if parsing or signature validation failed? You can catch `JwtException` and react accordingly:
@ -738,7 +738,7 @@ But what if parsing or signature validation failed? You can catch `JwtException
```java
try {
Jwts.parser().verifyWith(key).build().parseClaimsJws(compactJws);
Jwts.parser().verifyWith(key).build().parseSignedClaims(compactJws);
//OK, we can trust this JWT
@ -1071,7 +1071,7 @@ try {
.build() // (3)
.parse(compact); // (4) or parseClaimsJws, parseClaimsJwe, parseContentJws, etc
.parse(compact); // (4) or parseSignedClaims, parseEncryptedClaims, parseSignedContent, etc
// we can safely trust the JWT
@ -1085,7 +1085,7 @@ catch (JwtException ex) { // (5)
>
> **Type-safe JWTs:** If you are certain your parser will only ever encounter a specific kind of JWT (for example, you only
> ever use signed JWTs with `Claims` payloads, or encrypted JWTs with `byte[]` content payloads, etc), you can call the
> associated type-safe `parseClaimsJws`, `parseClaimsJwe`, (etc) method variant instead of the generic `parse` method.
> associated type-safe `parseSignedClaims`, `parseEncryptedClaims`, (etc) method variant instead of the generic `parse` method.
>
> These `parse*` methods will return the type-safe JWT you are expecting, for example, a `Jws<Claims>` or `Jwe<byte[]>`
> instead of a generic `Jwt<?,?>` instance.
@ -1108,7 +1108,7 @@ So which key do we use?
.verifyWith(secretKey) // <----
.build()
.parseClaimsJws(jwsString);
.parseSignedClaims(jwsString);
```
* If parsing a JWS and the JWS was signed with a `PrivateKey`, that key's corresponding `PublicKey` (not the
`PrivateKey`) should be specified on the `JwtParserBuilder`. For example:
@ -1119,7 +1119,7 @@ So which key do we use?
.verifyWith(publicKey) // <---- publicKey, not privateKey
.build()
.parseClaimsJws(jwsString);
.parseSignedClaims(jwsString);
```
* If parsing a JWE and the JWE was encrypted with direct encryption using a `SecretKey`, the same `SecretKey` should be
specified on the `JwtParserBuilder`. For example:
@ -1130,7 +1130,7 @@ So which key do we use?
.decryptWith(secretKey) // <---- or a Password from Keys.password(charArray)
.build()
.parseClaimsJwe(jweString);
.parseEncryptedClaims(jweString);
```
* If parsing a JWE and the JWE was encrypted with a key algorithm using with a `PublicKey`, that key's corresponding
`PrivateKey` (not the `PublicKey`) should be specified on the `JwtParserBuilder`. For example:
@ -1141,7 +1141,7 @@ So which key do we use?
.decryptWith(privateKey) // <---- privateKey, not publicKey
.build()
.parseClaimsJwe(jweString);
.parseEncryptedClaims(jweString);
```
#### Multiple Keys?
@ -1743,7 +1743,7 @@ You read (parse) a JWS as follows:
1. Use the `Jwts.parser()` method to create a `JwtParserBuilder` instance.
2. Call either [keyLocator](#key-locator) or `verifyWith` methods to determine the key used to verify the JWS signature.
3. Call the `build()` method on the `JwtParserBuilder` to return a thread-safe `JwtParser`.
4. Finally, call the `parseClaimsJws(String)` method with your jws `String`, producing the original JWS.
4. Finally, call the `parseSignedClaims(String)` method with your jws `String`, producing the original JWS.
5. The entire call is wrapped in a try/catch block in case parsing or signature validation fails. We'll cover
exceptions and causes for failure later.
@ -1753,17 +1753,17 @@ For example:
Jws<Claims> jws;
try {
jws = Jwts.parser() // (1)
jws = Jwts.parser() // (1)
.keyLocator(keyLocator) // (2) dynamically lookup verification keys based on each JWS
//.verifyWith(key) // or a static key used to verify all encountered JWSs
.keyLocator(keyLocator) // (2) dynamically lookup verification keys based on each JWS
//.verifyWith(key) // or a static key used to verify all encountered JWSs
.build() // (3)
.parseClaimsJws(jwsString); // (4) or parseContentJws(jwsString)
.build() // (3)
.parseSignedClaims(jwsString); // (4) or parseSignedContent(jwsString)
// we can safely trust the JWT
catch (JwtException ex) { // (5)
catch (JwtException ex) { // (5)
// we *cannot* use the JWT as intended by its creator
}
@ -1772,8 +1772,8 @@ catch (JwtException ex) { // (5)
> **Note**
>
> **Type-safe JWSs:**
> * If you are expecting a JWS with a Claims `payload`, call the `JwtParser`'s `parseClaimsJws` method.
> * If you are expecting a JWS with a content `payload`, call the `JwtParser`'s `parseContentJws` method.
> * If you are expecting a JWS with a Claims `payload`, call the `JwtParser`'s `parseSignedClaims` method.
> * If you are expecting a JWS with a content `payload`, call the `JwtParser`'s `parseSignedContent` method.
<a name="jws-read-key"></a>
#### Verification Key
@ -1793,7 +1793,7 @@ For example:
.verifyWith(secretKey) // <----
.build()
.parseClaimsJws(jwsString);
.parseSignedClaims(jwsString);
```
* If the jws was signed with a `PrivateKey`, that key's corresponding `PublicKey` (not the `PrivateKey`) should be
specified on the `JwtParserBuilder`. For example:
@ -1804,7 +1804,7 @@ For example:
.verifyWith(publicKey) // <---- publicKey, not privateKey
.build()
.parseClaimsJws(jwsString);
.parseSignedClaims(jwsString);
```
<a name="jws-read-key-locator"></a><a name="jws-read-key-resolver"></a> <!-- legacy anchors for old links -->
@ -1903,7 +1903,7 @@ To parse the resulting `jws` string, we need to do two things when creating the
```java
Jws<byte[]> parsed = Jwts.parser().verifyWith(testKey) // 1
.build()
.parseContentJws(jws, content); // 2
.parseSignedContent(jws, content); // 2
assertArrayEquals(content, parsed.getPayload());
```
@ -1953,17 +1953,17 @@ To parse the resulting `jws` string, we need to do two things when creating the
Jws<Claims> parsed = Jwts.parser().verifyWith(testKey) // 1
.critical().add("b64").and() // 2
.build()
.parseClaimsJws(jws);
.parseSignedClaims(jws);
assert "joe".equals(parsed.getPayload().getSubject());
assert "me".equals(parsed.getPayload().getIssuer());
```
Did you notice we used the `.parseClaimsJws(String)` method instead of `.parseClaimsJws(String, byte[])`? This is
Did you notice we used the `.parseSignedClaims(String)` method instead of `.parseSignedClaims(String, byte[])`? This is
because the non-detached payload is already present and JJWT has what it needs for signature verification.
Additionally, we needed to specify the `b64` critical value: because we're not using the two-argument
`parseClaimsJws(jws, content)` method, the parser has no way of knowing if you wish to allow or support unencoded
`parseSignedClaims(jws, content)` method, the parser has no way of knowing if you wish to allow or support unencoded
payloads. Unencoded payloads have additional security considerations as described above, so they are disabled by
the parser by default unless you indicate you want to support them by using `critical().add("b64")`.
@ -1973,7 +1973,7 @@ payload String's UTF-8 bytes instead:
```java
parsed = Jwts.parser().verifyWith(testKey)
.build()
.parseClaimsJws(jws, claimsString.getBytes(StandardCharsets.UTF_8)); // <---
.parseSignedClaims(jws, claimsString.getBytes(StandardCharsets.UTF_8)); // <---
```
<a name="jwe"></a>
@ -2367,7 +2367,7 @@ You read (parse) a JWE as follows:
1. Use the `Jwts.parser()` method to create a `JwtParserBuilder` instance.
2. Call either [keyLocator](#key-locator) or `decryptWith` methods to determine the key used to decrypt the JWE.
4. Call the `JwtParserBuilder`'s `build()` method to create a thread-safe `JwtParser`.
5. Parse the jwe string with the `JwtParser`'s `parseClaimsJwe` or `parseContentJwe` method.
5. Parse the jwe string with the `JwtParser`'s `parseEncryptedClaims` or `parseEncryptedContent` method.
6. Wrap the entire call is in a try/catch block in case decryption or integrity verification fails.
For example:
@ -2376,17 +2376,17 @@ For example:
Jwe<Claims> jwe;
try {
jwe = Jwts.parser() // (1)
jwe = Jwts.parser() // (1)
.keyLocator(keyLocator) // (2) dynamically lookup decryption keys based on each JWE
//.decryptWith(key) // or a static key used to decrypt all encountered JWEs
.keyLocator(keyLocator) // (2) dynamically lookup decryption keys based on each JWE
//.decryptWith(key) // or a static key used to decrypt all encountered JWEs
.build() // (3)
.parseClaimsJwe(jweString); // (4) or parseContentJwe(jweString);
.build() // (3)
.parseEncryptedClaims(jweString); // (4) or parseEncryptedContent(jweString);
// we can safely trust the JWT
catch (JwtException ex) { // (5)
catch (JwtException ex) { // (5)
// we *cannot* use the JWT as intended by its creator
}
@ -2395,8 +2395,8 @@ catch (JwtException ex) { // (5)
> **Note**
>
> **Type-safe JWEs:**
> * If you are expecting a JWE with a Claims `payload`, call the `JwtParser`'s `parseClaimsJwe` method.
> * If you are expecting a JWE with a content `payload`, call the `JwtParser`'s `parseContentJwe` method.
> * If you are expecting a JWE with a Claims `payload`, call the `JwtParser`'s `parseEncryptedClaims` method.
> * If you are expecting a JWE with a content `payload`, call the `JwtParser`'s `parseEncryptedContent` method.
<a name="jwe-read-key"></a>
#### Decryption Key
@ -2415,7 +2415,7 @@ So which key do we use for decryption?
.decryptWith(secretKey) // <----
.build()
.parseClaimsJwe(jweString);
.parseEncryptedClaims(jweString);
```
* If the jwe was encrypted using a key produced by a Password-based key derivation `KeyAlgorithm`, the same
`Password` must be specified on the `JwtParserBuilder`. For example:
@ -2428,7 +2428,7 @@ So which key do we use for decryption?
.decryptWith(password) // <---- an `io.jsonwebtoken.security.Password` instance
.build()
.parseClaimsJwe(jweString);
.parseEncryptedClaims(jweString);
```
* If the jwe was encrypted with a key produced by an asymmetric `KeyAlgorithm`, the corresponding `PrivateKey` (not
the `PublicKey`) must be specified on the `JwtParserBuilder`. For example:
@ -2439,7 +2439,7 @@ So which key do we use for decryption?
.decryptWith(privateKey) // <---- a `PrivateKey`, not a `PublicKey`
.build()
.parseClaimsJws(jweString);
.parseSignedClaims(jweString);
```
<a name="jwe-key-locator"></a>
@ -2486,7 +2486,7 @@ PrivateKey decryptionKey = Keys.builder(pkcs11PrivateKey).publicKey(pkcs11Public
Jwts.parser()
.decryptWith(decryptionKey) // <----
.build()
.parseClaimsJwe(jweString);
.parseEncryptedClaims(jweString);
```
Or as the return value from your key locator:
@ -2495,7 +2495,7 @@ Or as the return value from your key locator:
Jwts.parser()
.keyLocator(keyLocator) // your keyLocator.locate(header) would return Keys.builder...
.build()
.parseClaimsJwe(jweString);
.parseEncryptedClaims(jweString);
```
Please see the [Provider-constrained Keys](#key-locator-provider) section for more information, as well as
@ -3022,11 +3022,11 @@ Jwts.parser()
.build()
.parseClaimsJwt(aJwtString)
.parseUnprotectedClaims(aJwtString)
.getPayload()
.get("user", User.class) // <-----
.get("user", User.class); // <-----
```
> **Note**
@ -3308,7 +3308,7 @@ byte[] content = message.getBytes(StandardCharsets.UTF_8);
String jws = Jwts.builder().content(content, "text/plain").signWith(key, alg).compact();
// Parse the compact JWS:
content = Jwts.parser().verifyWith(key).build().parseContentJws(jws).getPayload();
content = Jwts.parser().verifyWith(key).build().parseSignedContent(jws).getPayload();
assert message.equals(new String(content, StandardCharsets.UTF_8));
```
@ -3336,7 +3336,7 @@ String jws = Jwts.builder().subject("Alice")
// Alice receives and verifies the compact JWS came from Bob:
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- Bob's RSA public key
.build().parseClaimsJws(jws).getPayload().getSubject();
.build().parseSignedClaims(jws).getPayload().getSubject();
assert "Alice".equals(subject);
```
@ -3367,7 +3367,7 @@ String jws = Jwts.builder().subject("Alice")
// Alice receives and verifies the compact JWS came from Bob:
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- Bob's EC public key
.build().parseClaimsJws(jws).getPayload().getSubject();
.build().parseSignedClaims(jws).getPayload().getSubject();
assert "Alice".equals(subject);
```
@ -3411,7 +3411,7 @@ String jws = Jwts.builder().subject("Alice")
// Alice receives and verifies the compact JWS came from Bob:
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- Bob's Edwards Curve public key
.build().parseClaimsJws(jws).getPayload().getSubject();
.build().parseSignedClaims(jws).getPayload().getSubject();
assert "Alice".equals(subject);
```
@ -3450,7 +3450,7 @@ byte[] content = message.getBytes(StandardCharsets.UTF_8);
String jwe = Jwts.builder().content(content, "text/plain").encryptWith(key, enc).compact();
// Parse the compact JWE:
content = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe).getPayload();
content = Jwts.parser().decryptWith(key).build().parseEncryptedContent(jwe).getPayload();
assert message.equals(new String(content, StandardCharsets.UTF_8));
```
@ -3484,7 +3484,7 @@ String jwe = Jwts.builder().audience().add("Alice").and()
// Alice receives and decrypts the compact JWE:
Set<String> audience = Jwts.parser()
.decryptWith(pair.getPrivate()) // <-- Alice's RSA private key
.build().parseClaimsJwe(jwe).getPayload().getAudience();
.build().parseEncryptedClaims(jwe).getPayload().getAudience();
assert audience.contains("Alice");
```
@ -3516,7 +3516,7 @@ String jwe = Jwts.builder().issuer("me").encryptWith(key, alg, enc).compact();
// Parse the compact JWE:
String issuer = Jwts.parser().decryptWith(key).build()
.parseClaimsJwe(jwe).getPayload().getIssuer();
.parseEncryptedClaims(jwe).getPayload().getIssuer();
assert "me".equals(issuer);
```
@ -3552,7 +3552,7 @@ String jwe = Jwts.builder().audience().add("Alice").and()
// Alice receives and decrypts the compact JWE:
Set<String> audience = Jwts.parser()
.decryptWith(pair.getPrivate()) // <-- Alice's EC private key
.build().parseClaimsJwe(jwe).getPayload().getAudience();
.build().parseEncryptedClaims(jwe).getPayload().getAudience();
assert audience.contains("Alice");
```
@ -3598,7 +3598,7 @@ String jwe = Jwts.builder().issuer("me")
// Parse the compact JWE:
String issuer = Jwts.parser().decryptWith(password)
.build().parseClaimsJwe(jwe).getPayload().getIssuer();
.build().parseEncryptedClaims(jwe).getPayload().getIssuer();
assert "me".equals(issuer);
```

View File

@ -24,6 +24,38 @@ package io.jsonwebtoken;
*/
public interface Jwe<B> extends ProtectedJwt<JweHeader, B> {
/**
* Visitor implementation that ensures the visited JWT is a JSON Web Encryption ('JWE') message with an
* authenticated and decrypted {@code byte[]} array payload, and rejects all others with an
* {@link UnsupportedJwtException}.
*
* @see SupportedJwtVisitor#onDecryptedContent(Jwe)
* @since JJWT_RELEASE_VERSION
*/
@SuppressWarnings("UnnecessaryModifier")
public static final JwtVisitor<Jwe<byte[]>> CONTENT = new SupportedJwtVisitor<Jwe<byte[]>>() {
@Override
public Jwe<byte[]> onDecryptedContent(Jwe<byte[]> jwe) {
return jwe;
}
};
/**
* Visitor implementation that ensures the visited JWT is a JSON Web Encryption ('JWE') message with an
* authenticated and decrypted {@link Claims} payload, and rejects all others with an
* {@link UnsupportedJwtException}.
*
* @see SupportedJwtVisitor#onDecryptedClaims(Jwe)
* @since JJWT_RELEASE_VERSION
*/
@SuppressWarnings("UnnecessaryModifier")
public static final JwtVisitor<Jwe<Claims>> CLAIMS = new SupportedJwtVisitor<Jwe<Claims>>() {
@Override
public Jwe<Claims> onDecryptedClaims(Jwe<Claims> jwe) {
return jwe;
}
};
/**
* Returns the Initialization Vector used during JWE encryption and decryption.
*

View File

@ -18,10 +18,42 @@ package io.jsonwebtoken;
/**
* An expanded (not compact/serialized) Signed JSON Web Token.
*
* @param <B> the type of the JWS body contents, either a String or a {@link Claims} instance.
* @param <P> the type of the JWS payload, either a byte[] or a {@link Claims} instance.
* @since 0.1
*/
public interface Jws<B> extends ProtectedJwt<JwsHeader, B> {
public interface Jws<P> extends ProtectedJwt<JwsHeader, P> {
/**
* 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 JJWT_RELEASE_VERSION
*/
@SuppressWarnings("UnnecessaryModifier")
public static final JwtVisitor<Jws<byte[]>> CONTENT = new SupportedJwtVisitor<Jws<byte[]>>() {
@Override
public Jws<byte[]> onVerifiedContent(Jws<byte[]> 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 JJWT_RELEASE_VERSION
*/
@SuppressWarnings("UnnecessaryModifier")
public static final JwtVisitor<Jws<Claims>> CLAIMS = new SupportedJwtVisitor<Jws<Claims>>() {
@Override
public Jws<Claims> onVerifiedClaims(Jws<Claims> jws) {
return jws;
}
};
/**
* Returns the verified JWS signature as a Base64Url string.

View File

@ -24,6 +24,36 @@ package io.jsonwebtoken;
*/
public interface Jwt<H extends Header, P> {
/**
* 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 JJWT_RELEASE_VERSION
*/
@SuppressWarnings("UnnecessaryModifier")
public static final JwtVisitor<Jwt<Header, byte[]>> UNSECURED_CONTENT = new SupportedJwtVisitor<Jwt<Header, byte[]>>() {
@Override
public Jwt<Header, byte[]> onUnsecuredContent(Jwt<Header, byte[]> 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 JJWT_RELEASE_VERSION
*/
@SuppressWarnings("UnnecessaryModifier")
public static final JwtVisitor<Jwt<Header, Claims>> UNSECURED_CLAIMS = new SupportedJwtVisitor<Jwt<Header, Claims>>() {
@Override
public Jwt<Header, Claims> onUnsecuredClaims(Jwt<Header, Claims> jwt) {
return jwt;
}
};
/**
* Returns the JWT {@link Header} or {@code null} if not present.
*
@ -54,4 +84,13 @@ public interface Jwt<H extends Header, P> {
* @since JJWT_RELEASE_VERSION
*/
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 <T> the value type returned from the {@code visit} method.
* @return the value returned from visitor's {@code visit} method implementation.
*/
<T> T accept(JwtVisitor<T> visitor);
}

View File

@ -21,17 +21,20 @@ package io.jsonwebtoken;
*
* @param <T> the type of object to return to the parser caller after handling the parsed JWT.
* @since 0.2
* @deprecated since JJWT_RELEASE_VERSION in favor of calling {@link Jwt#accept(JwtVisitor)}.
*/
public interface JwtHandler<T> {
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
public interface JwtHandler<T> extends JwtVisitor<T> {
/**
* This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is
* an unprotected content JWT. An unprotected content JWT has a byte array payload that is not
* 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.
*
* @param jwt the parsed Unprotected content JWT
* @param jwt the parsed unsecured content JWT
* @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary.
*/
T onContentJwt(Jwt<Header, byte[]> jwt);

View File

@ -28,7 +28,7 @@ package io.jsonwebtoken;
* @param <T> the type of object to return to the parser caller after handling the parsed JWT.
* @since 0.2
*/
public abstract class JwtHandlerAdapter<T> implements JwtHandler<T> {
public abstract class JwtHandlerAdapter<T> extends SupportedJwtVisitor<T> implements JwtHandler<T> {
/**
* Default constructor, does not initialize any internal state.
@ -36,33 +36,63 @@ public abstract class JwtHandlerAdapter<T> implements JwtHandler<T> {
public JwtHandlerAdapter() {
}
@Override
public T onUnsecuredContent(Jwt<Header, byte[]> jwt) {
return onContentJwt(jwt); // bridge for existing implementations
}
@Override
public T onUnsecuredClaims(Jwt<Header, Claims> jwt) {
return onClaimsJwt(jwt);
}
@Override
public T onVerifiedContent(Jws<byte[]> jws) {
return onContentJws(jws);
}
@Override
public T onVerifiedClaims(Jws<Claims> jws) {
return onClaimsJws(jws);
}
@Override
public T onDecryptedContent(Jwe<byte[]> jwe) {
return onContentJwe(jwe);
}
@Override
public T onDecryptedClaims(Jwe<Claims> jwe) {
return onClaimsJwe(jwe);
}
@Override
public T onContentJwt(Jwt<Header, byte[]> jwt) {
throw new UnsupportedJwtException("Unprotected content JWTs are not supported.");
return super.onUnsecuredContent(jwt);
}
@Override
public T onClaimsJwt(Jwt<Header, Claims> jwt) {
throw new UnsupportedJwtException("Unprotected Claims JWTs are not supported.");
return super.onUnsecuredClaims(jwt);
}
@Override
public T onContentJws(Jws<byte[]> jws) {
throw new UnsupportedJwtException("Signed content JWTs are not supported.");
return super.onVerifiedContent(jws);
}
@Override
public T onClaimsJws(Jws<Claims> jws) {
throw new UnsupportedJwtException("Signed Claims JWTs are not supported.");
return super.onVerifiedClaims(jws);
}
@Override
public T onContentJwe(Jwe<byte[]> jwe) {
throw new UnsupportedJwtException("Encrypted content JWTs are not supported.");
return super.onDecryptedContent(jwe);
}
@Override
public T onClaimsJwe(Jwe<Claims> jwe) {
throw new UnsupportedJwtException("Encrypted Claims JWTs are not supported.");
return super.onDecryptedClaims(jwe);
}
}

View File

@ -22,6 +22,7 @@ import io.jsonwebtoken.security.SignatureException;
import java.io.InputStream;
/**
* 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
@ -45,13 +46,29 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* Parses the specified compact serialized JWT string based on the builder's current configuration state and
* returns the resulting JWT, JWS, or JWE instance.
*
* <p>This method returns a JWT, JWS, or JWE based on the parsed string. Because it may be cumbersome to
* determine if it is a JWT, JWS or JWE, or if the payload is a Claims or byte array with {@code instanceof} checks,
* the {@link #parse(CharSequence, JwtHandler) parse(String,JwtHandler)} method allows for a type-safe callback approach
* that may help reduce code or instanceof checks.</p>
* <p>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:</p>
*
* <blockquote><pre>
* // NOT RECOMMENDED:
* Jwt&lt;?,?&gt; jwt = parser.parse(input);
* if (jwt instanceof Jwe&lt;?&gt;) {
* Jwe&lt;?&gt; jwe = (Jwe&lt;?&gt;)jwt;
* if (jwe.getPayload() instanceof Claims) {
* Jwe&lt;Claims&gt; claimsJwe = (Jwe&lt;Claims&gt;)jwe;
* // do something with claimsJwe
* }
* }</pre></blockquote>
*
* <p>the following alternative is usually preferred:</p>
*
* <blockquote><pre>
* Jwe&lt;Claims&gt; jwe = parser.parse(input).accept({@link Jwe#CLAIMS});</pre></blockquote>
*
* @param jwt the compact serialized JWT to parse
* @return the specified compact serialized JWT string based on the builder's current configuration state.
* @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
@ -60,47 +77,20 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* @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(CharSequence, JwtHandler)
* @see #parseContentJwt(CharSequence)
* @see #parseClaimsJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parseContentJwe(CharSequence)
* @see #parseClaimsJwe(CharSequence)
* @see Jwt#accept(JwtVisitor)
*/
Jwt<?, ?> parse(CharSequence jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException,
SecurityException, IllegalArgumentException;
/**
* 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, JWS, or JWE instance.
* Deprecated since JJWT_RELEASE_VERSION 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:
*
* <p>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:</p>
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jwt).{@link Jwt#accept(JwtVisitor) accept}({@link JwtVisitor visitor});</pre></blockquote>
*
* <pre>
* String compactJwt = request.getParameter("jwt"); //we are confident this is a signed JWS
*
* String subject = Jwts.parser().verifyWith(key).build().parse(compactJwt, new JwtHandlerAdapter&lt;String&gt;() {
* &#64;Override
* public String onClaimsJws(Jws&lt;Claims&gt; jws) {
* return jws.getBody().getSubject();
* }
* });
* </pre>
*
* <p>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:</p>
*
* <ul>
* <li>{@link #parseContentJwt(CharSequence)}</li>
* <li>{@link #parseClaimsJwt(CharSequence)}</li>
* <li>{@link #parseContentJws(CharSequence)}</li>
* <li>{@link #parseClaimsJws(CharSequence)}</li>
* <li>{@link #parseContentJwe(CharSequence)}</li>
* <li>{@link #parseClaimsJwe(CharSequence)}</li>
* </ul>
* <p>This method will be removed before the 1.0 release.</p>
*
* @param jwt the compact serialized JWT to parse
* @param handler the handler to invoke when encountering a specific type of JWT
@ -115,117 +105,175 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* 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 #parseContentJwt(CharSequence)
* @see #parseClaimsJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parseContentJwe(CharSequence)
* @see #parseClaimsJwe(CharSequence)
* @see #parse(CharSequence)
* @see Jwt#accept(JwtVisitor)
* @since 0.2
* @deprecated since JJWT_RELEASE_VERSION in favor of
* <code>{@link #parse(CharSequence)}.{@link Jwt#accept(JwtVisitor) accept}({@link JwtVisitor visitor});</code>
*/
@Deprecated
<T> T parse(CharSequence jwt, JwtHandler<T> handler) throws ExpiredJwtException, UnsupportedJwtException,
MalformedJwtException, SignatureException, SecurityException, IllegalArgumentException;
/**
* Parses the specified compact serialized JWT string based on the builder's current configuration state and
* returns the resulting unprotected content JWT instance. 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.
* Deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseUnsecuredContent(CharSequence)}.
*
* <p>This is a convenience method that is usable if you are confident that the compact string argument reflects an
* unprotected content JWT. An unprotected content JWT has a byte array payload and it 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.</p>
* <p>This method will be removed before the 1.0 release.</p>
*
* <p><b>If the compact string presented does not reflect an unprotected content JWT with byte array payload,
* an {@link UnsupportedJwtException} will be thrown.</b></p>
*
* @param jwt a compact serialized unprotected content JWT string.
* @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 unprotected content JWT
* @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 #parseClaimsJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parse(CharSequence, JwtHandler)
* @see #parse(CharSequence)
* @see #parseUnsecuredContent(CharSequence)
* @see Jwt#accept(JwtVisitor)
* @since 0.2
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseUnsecuredContent(CharSequence)}.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
Jwt<Header, byte[]> parseContentJwt(CharSequence jwt) throws UnsupportedJwtException, MalformedJwtException,
SignatureException, SecurityException, IllegalArgumentException;
/**
* Parses the specified compact serialized JWT string based on the builder's current configuration state and
* returns the resulting unprotected Claims JWT instance.
* Deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseUnsecuredClaims(CharSequence)}.
*
* <p>This is a convenience method that is usable if you are confident that the compact string argument reflects an
* unprotected Claims JWT. An unprotected Claims JWT has a {@link Claims} payload and it is not cryptographically
* signed or encrypted.</p>
* <p>This method will be removed before the 1.0 release.</p>
*
* <p><b>If the compact string presented does not reflect an unprotected Claims JWT, an
* {@link UnsupportedJwtException} will be thrown.</b></p>
*
* @param jwt a compact serialized unprotected Claims JWT string.
* @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 unprotected Claims JWT
* @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 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 jwt} string is {@code null} or empty or only whitespace
* @see #parseContentJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parse(CharSequence, JwtHandler)
* @see #parse(CharSequence)
* @see #parseUnsecuredClaims(CharSequence)
* @see Jwt#accept(JwtVisitor)
* @since 0.2
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseUnsecuredClaims(CharSequence)}.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
Jwt<Header, Claims> parseClaimsJwt(CharSequence jwt) throws ExpiredJwtException, UnsupportedJwtException,
MalformedJwtException, SignatureException, SecurityException, IllegalArgumentException;
/**
* Parses the specified compact serialized JWS string based on the builder's current configuration state and
* returns the resulting content JWS instance. 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.
* Deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseSignedContent(CharSequence)}.
*
* <p>This is a convenience method that is usable if you are confident that the compact string argument reflects a
* content JWS. A content JWS is a JWT with a byte array payload that has been cryptographically signed.</p>
* <p>This method will be removed before the 1.0 release.</p>
*
* <p><b>If the compact string presented does not reflect a content JWS, an {@link UnsupportedJwtException}
* will be thrown.</b></p>
*
* @param jws a compact serialized JWS string.
* @return the {@link Jws Jws} instance that reflects the specified compact JWS string.
* @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 #parseContentJwt(CharSequence)
* @see #parseContentJwe(CharSequence)
* @see #parseClaimsJwt(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parseClaimsJwe(CharSequence)
* @see #parse(CharSequence, JwtHandler)
* @see #parseSignedContent(CharSequence)
* @see #parseEncryptedContent(CharSequence)
* @see #parse(CharSequence)
* @since 0.2
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseSignedContent(CharSequence)}.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
Jws<byte[]> parseContentJws(CharSequence jws) throws UnsupportedJwtException, MalformedJwtException, SignatureException,
SecurityException, IllegalArgumentException;
/**
* Deprecated since JJWT_RELEASE_VERSION in favor of {@link #parseSignedClaims(CharSequence)}.
*
* @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 JJWT_RELEASE_VERSION in favor of {@link #parseSignedClaims(CharSequence)}.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
Jws<Claims> parseClaimsJws(CharSequence jws) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException,
SignatureException, SecurityException, IllegalArgumentException;
/**
* 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.
*
* <p>This is a convenience method logically equivalent to the following:</p>
*
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jwt).{@link Jwt#accept(JwtVisitor) accept}({@link
* Jwt#UNSECURED_CONTENT});</pre></blockquote>
*
* @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 JJWT_RELEASE_VERSION
*/
Jwt<Header, byte[]> parseUnsecuredContent(CharSequence jwt) throws JwtException, IllegalArgumentException;
/**
* Parses the {@code jwt} argument, expected to be an unsecured {@code Claims} JWT. This is a
* convenience method logically equivalent to the following:
*
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jwt).{@link Jwt#accept(JwtVisitor) accept}({@link
* Jwt#UNSECURED_CLAIMS});</pre></blockquote>
*
* @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 JJWT_RELEASE_VERSION
*/
Jwt<Header, Claims> parseUnsecuredClaims(CharSequence jwt) throws JwtException, IllegalArgumentException;
/**
* 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.
*
* <p>This is a convenience method logically equivalent to the following:</p>
*
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jws).{@link Jwt#accept(JwtVisitor) accept}({@link
* Jws#CONTENT});</pre></blockquote>
*
* @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 JJWT_RELEASE_VERSION
*/
Jws<byte[]> parseSignedContent(CharSequence jws) throws JwtException, IllegalArgumentException;
/**
* Parses a JWS known to use the
* <a href="https://datatracker.ietf.org/doc/html/rfc7797">RFC 7797: JSON Web Signature (JWS) Unencoded Payload
* Option</a>, using the specified {@code unencodedPayload} for signature verification.
*
* <p><b>Unencoded Non-Detached Payload</b></p>
*
* <p>Note that if the JWS contains a valid unencoded Payload string (what RFC 7797 calls an
* &quot;<a href="https://datatracker.ietf.org/doc/html/rfc7797#section-5.2">unencoded non-detached
* payload</a>&quot;, the {@code unencodedPayload} method argument will be ignored, as the JWS already includes
@ -234,25 +282,9 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* @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 JJWT_RELEASE_VERSION
*/
Jws<byte[]> parseContentJws(CharSequence jws, byte[] unencodedPayload);
/**
* Parses a JWS known to use the
* <a href="https://datatracker.ietf.org/doc/html/rfc7797">RFC 7797: JSON Web Signature (JWS) Unencoded Payload
* Option</a>, using the specified {@code unencodedPayload} for signature verification.
*
* <p><b>Unencoded Non-Detached Payload</b></p>
* <p>Note that if the JWS contains a valid unencoded payload String (what RFC 7797 calls an
* &quot;<a href="https://datatracker.ietf.org/doc/html/rfc7797#section-5.2">unencoded non-detached
* payload</a>&quot;, the {@code unencodedPayload} method argument will be ignored, as the JWS already includes
* the payload content necessary for signature verification and claims creation.</p>
*
* @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.
*/
Jws<Claims> parseClaimsJws(CharSequence jws, byte[] unencodedPayload);
Jws<byte[]> parseSignedContent(CharSequence jws, byte[] unencodedPayload);
/**
* Parses a JWS known to use the
@ -265,6 +297,7 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* may obtain them independently before or after calling this method if they are needed otherwise.</p>
*
* <p><b>Unencoded Non-Detached Payload</b></p>
*
* <p>Note that if the JWS contains a valid unencoded payload String (what RFC 7797 calls an
* &quot;<a href="https://datatracker.ietf.org/doc/html/rfc7797#section-5.2">unencoded non-detached
* payload</a>&quot;, the {@code unencodedPayload} method argument will be ignored, as the JWS already includes
@ -274,8 +307,49 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* @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 JJWT_RELEASE_VERSION
*/
Jws<byte[]> parseContentJws(CharSequence jws, InputStream unencodedPayload);
Jws<byte[]> parseSignedContent(CharSequence jws, InputStream unencodedPayload);
/**
* Parses the {@code jws} argument, expected to be a cryptographically-signed {@code Claims} JWS. This is a
* convenience method logically equivalent to the following:
*
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jws).{@link Jwt#accept(JwtVisitor) accept}({@link
* Jws#CLAIMS});</pre></blockquote>
*
* @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 JJWT_RELEASE_VERSION
*/
Jws<Claims> parseSignedClaims(CharSequence jws) throws JwtException, IllegalArgumentException;
/**
* Parses a JWS known to use the
* <a href="https://datatracker.ietf.org/doc/html/rfc7797">RFC 7797: JSON Web Signature (JWS) Unencoded Payload
* Option</a>, using the specified {@code unencodedPayload} for signature verification.
*
* <p><b>Unencoded Non-Detached Payload</b></p>
*
* <p>Note that if the JWS contains a valid unencoded payload String (what RFC 7797 calls an
* &quot;<a href="https://datatracker.ietf.org/doc/html/rfc7797#section-5.2">unencoded non-detached
* payload</a>&quot;, the {@code unencodedPayload} method argument will be ignored, as the JWS already includes
* the payload content necessary for signature verification and claims creation.</p>
*
* @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 JJWT_RELEASE_VERSION
*/
Jws<Claims> parseSignedClaims(CharSequence jws, byte[] unencodedPayload) throws JwtException, IllegalArgumentException;
/**
* Parses a JWS known to use the
@ -286,9 +360,11 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
* <p><b>NOTE:</b> 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 #parseContentJws(CharSequence, InputStream)} method instead.</p>
* large Claims), it is recommended to use the {@link #parseSignedContent(CharSequence, InputStream)} method
* instead.</p>
*
* <p><b>Unencoded Non-Detached Payload</b></p>
*
* <p>Note that if the JWS contains a valid unencoded Payload string (what RFC 7797 calls an
* &quot;<a href="https://datatracker.ietf.org/doc/html/rfc7797#section-5.2">unencoded non-detached
* payload</a>&quot;, the {@code unencodedPayload} method argument will be ignored, as the JWS already includes
@ -296,98 +372,51 @@ public interface JwtParser extends Parser<Jwt<?, ?>> {
*
* @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.
* @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 JJWT_RELEASE_VERSION
*/
Jws<Claims> parseClaimsJws(CharSequence jws, InputStream unencodedPayload);
Jws<Claims> parseSignedClaims(CharSequence jws, InputStream unencodedPayload) throws JwtException, IllegalArgumentException;
/**
* Parses the specified compact serialized JWS string based on the builder's current configuration state and
* returns the resulting Claims JWS instance.
* 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.
*
* <p>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} payload that has been cryptographically signed.</p>
* <p>This is a convenience method logically equivalent to the following:</p>
*
* <p><b>If the compact string presented does not reflect a Claims JWS, an {@link UnsupportedJwtException} will be
* thrown.</b></p>
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jwe).{@link Jwt#accept(JwtVisitor) accept}({@link
* Jwe#CONTENT});</pre></blockquote>
*
* @param jws 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 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 #parseContentJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseContentJwe(CharSequence)
* @see #parseClaimsJwt(CharSequence)
* @see #parseClaimsJwe(CharSequence)
* @see #parse(CharSequence, JwtHandler)
* @see #parse(CharSequence)
* @since 0.2
*/
Jws<Claims> parseClaimsJws(CharSequence jws) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException,
SignatureException, SecurityException, IllegalArgumentException;
/**
* Parses the specified compact serialized JWE string based on the builder's current configuration state and
* returns the resulting content JWE instance. 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.
*
* <p>This is a convenience method that is usable if you are confident that the compact string argument reflects a
* content JWE. A content JWE is a JWT with a byte array payload that has been encrypted.</p>
*
* <p><b>If the compact string presented does not reflect a content JWE, an {@link UnsupportedJwtException}
* will be thrown.</b></p>
*
* @param jwe a compact serialized JWE string.
* @return the {@link Jwe Jwe} instance that reflects the specified compact JWE string.
* @throws UnsupportedJwtException if the {@code jwe} argument does not represent a content JWE
* @throws MalformedJwtException if the {@code jwe} string is not a valid JWE
* @throws SecurityException if the {@code jwe} JWE decryption fails
* @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 #parseContentJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseClaimsJwt(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parseClaimsJwe(CharSequence)
* @see #parse(CharSequence, JwtHandler)
* @see #parse(CharSequence)
* @see Jwt#accept(JwtVisitor)
* @since JJWT_RELEASE_VERSION
*/
Jwe<byte[]> parseContentJwe(CharSequence jwe) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException,
SecurityException, IllegalArgumentException;
Jwe<byte[]> parseEncryptedContent(CharSequence jwe) throws JwtException, IllegalArgumentException;
/**
* Parses the specified compact serialized JWE string based on the builder's current configuration state and
* returns the resulting Claims JWE instance.
* Parses the {@code jwe} argument, expected to be an encrypted {@code Claims} JWE. This is a
* convenience method logically equivalent to the following:
*
* <p>This is a convenience method that is usable if you are confident that the compact string argument reflects a
* Claims JWE. A Claims JWE is a JWT with a {@link Claims} payload that has been encrypted.</p>
* <blockquote><pre>
* {@link #parse(CharSequence) parse}(jwe).{@link Jwt#accept(JwtVisitor) accept}({@link
* Jwe#CLAIMS});</pre></blockquote>
*
* <p><b>If the compact string presented does not reflect a Claims JWE, an {@link UnsupportedJwtException} will be
* thrown.</b></p>
*
* @param jwe a compact serialized Claims JWE string.
* @return the {@link Jwe Jwe} instance that reflects the specified compact Claims JWE string.
* @throws UnsupportedJwtException if the {@code claimsJwe} argument does not represent a Claims JWE
* @throws MalformedJwtException if the {@code claimsJwe} string is not a valid JWE
* @throws SignatureException if the {@code claimsJwe} JWE decryption fails
* @throws ExpiredJwtException if the specified JWT is a Claims JWE and the Claims has an expiration time
* before the time this method is invoked.
* @throws IllegalArgumentException if the {@code claimsJwe} string is {@code null} or empty or only whitespace
* @see #parseContentJwt(CharSequence)
* @see #parseContentJws(CharSequence)
* @see #parseContentJwe(CharSequence)
* @see #parseClaimsJwt(CharSequence)
* @see #parseClaimsJws(CharSequence)
* @see #parse(CharSequence, JwtHandler)
* @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 JJWT_RELEASE_VERSION
*/
Jwe<Claims> parseClaimsJwe(CharSequence jwe) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException,
SecurityException, IllegalArgumentException;
Jwe<Claims> parseEncryptedClaims(CharSequence jwe) throws JwtException, IllegalArgumentException;
}

View File

@ -467,7 +467,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
* }
* }})
* .build()
* .parseClaimsJws(compact);
* .parseSignedClaims(compact);
* </pre>
*
* <p>A Key {@code Locator} is invoked once during parsing before performing decryption or signature verification.</p>
@ -535,7 +535,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
* //inspect the header or claims, lookup and return the signing key
* return getSigningKey(header, claims); //implement me
* }})
* .build().parseClaimsJws(compact);
* .build().parseSignedClaims(compact);
* </pre>
*
* <p>A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.</p>

View File

@ -0,0 +1,68 @@
/*
* Copyright © 2023 jsonwebtoken.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jsonwebtoken;
/**
* A JwtVisitor supports the <a href="https://en.wikipedia.org/wiki/Visitor_pattern">Visitor design pattern</a> for
* {@link Jwt} instances. Visitor implementations define logic for a specific JWT subtype or payload subtype
* avoiding type-checking if-then-else conditionals in favor of type-safe method dispatch when encountering a JWT.
*
* @param <T> the type of object to return after invoking the {@link Jwt#accept(JwtVisitor)} method.
* @since JJWT_RELEASE_VERSION
*/
public interface JwtVisitor<T> {
/**
* Handles an encountered Unsecured JWT that has not been cryptographically secured at all. Implementations can
* check the {@link Jwt#getPayload()} to determine if it is a {@link Claims} instance or a {@code byte[]} array.
*
* <p>If the payload is a {@code byte[]} array, and the JWT creator has set the (optional)
* {@link Header#getContentType()} value, the application may inspect that value to determine how to convert
* the byte array to the final type as desired.</p>
*
* @param jwt the parsed Unsecured JWT.
* @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary.
*/
T visit(Jwt<?, ?> jwt);
/**
* Handles an encountered JSON Web Signature (aka 'JWS') message that has been cryptographically
* verified/authenticated. Implementations can check the {@link Jwt#getPayload()} determine if it is a
* {@link Claims} instance or a {@code byte[]} array.
*
* <p>If the payload is a {@code byte[]} array, and the JWS creator has set the (optional)
* {@link Header#getContentType()} value, the application may inspect that value to determine how to convert
* the byte array to the final type as desired.</p>
*
* @param jws the parsed verified/authenticated JWS.
* @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary.
*/
T visit(Jws<?> jws);
/**
* Handles an encountered JSON Web Encryption (aka 'JWE') message that has been authenticated and decrypted.
* Implementations can check the (decrypted) {@link Jwt#getPayload()} to determine if it is a {@link Claims}
* instance or a {@code byte[]} array.
*
* <p>If the payload is a {@code byte[]} array, and the JWE creator has set the (optional)
* {@link Header#getContentType()} value, the application may inspect that value to determine how to convert
* the byte array to the final type as desired.</p>
*
* @param jwe the parsed authenticated and decrypted JWE.
* @return any object to be used after inspecting the JWE, or {@code null} if no return value is necessary.
*/
T visit(Jwe<?> jwe);
}

View File

@ -33,7 +33,7 @@ import java.security.Key;
* //inspect the header or claims, lookup and return the signing key
* return getSigningKeyBytes(header, claims); //implement me
* }})
* .build().parseClaimsJws(compact);
* .build().parseSignedClaims(compact);
* </pre>
*
* <p>A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.</p>

View File

@ -0,0 +1,200 @@
/*
* Copyright © 2023 jsonwebtoken.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jsonwebtoken;
import io.jsonwebtoken.lang.Assert;
/**
* A {@code JwtVisitor} that guarantees only supported JWT instances are handled, rejecting
* all other (unsupported) JWTs with {@link UnsupportedJwtException}s. A JWT is considered supported
* only if the type-specific handler method is overridden by a subclass.
*
* @param <T> the type of value returned from the subclass handler method implementation.
* @since JJWT_RELEASE_VERSION
*/
public class SupportedJwtVisitor<T> implements JwtVisitor<T> {
/**
* Default constructor, does not initialize any internal state.
*/
public SupportedJwtVisitor() {
}
/**
* Handles an encountered unsecured JWT by delegating to either {@link #onUnsecuredContent(Jwt)} or
* {@link #onUnsecuredClaims(Jwt)} depending on the payload type.
*
* @param jwt the parsed unsecured JWT
* @return the value returned by either {@link #onUnsecuredContent(Jwt)} or {@link #onUnsecuredClaims(Jwt)}
* depending on the payload type.
* @throws UnsupportedJwtException if the payload is neither a {@code byte[]} nor {@code Claims}, or either
* delegate method throws the same.
*/
@SuppressWarnings("unchecked")
@Override
public T visit(Jwt<?, ?> jwt) {
Assert.notNull(jwt, "JWT cannot be null.");
Object payload = jwt.getPayload();
if (payload instanceof byte[]) {
return onUnsecuredContent((Jwt<Header, byte[]>) jwt);
} else {
// only other type we support:
Assert.stateIsInstance(Claims.class, payload, "Unexpected payload data type: ");
return onUnsecuredClaims((Jwt<Header, Claims>) jwt);
}
}
/**
* Handles an encountered unsecured content JWT - one that is not cryptographically signed nor
* encrypted, and has a byte[] array payload. If the JWT creator has set the (optional)
* {@link Header#getContentType()} value, the application may inspect that value to determine how to convert
* the byte array to the final type as desired.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jwt the parsed unsecured content JWT
* @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onUnsecuredContent(Jwt<Header, byte[]> jwt) throws UnsupportedJwtException {
throw new UnsupportedJwtException("Unexpected unsecured content JWT.");
}
/**
* Handles an encountered unsecured Claims JWT - one that is not cryptographically signed nor
* encrypted, and has a {@link Claims} payload.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jwt the parsed unsecured content JWT
* @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onUnsecuredClaims(Jwt<Header, Claims> jwt) {
throw new UnsupportedJwtException("Unexpected unsecured Claims JWT.");
}
/**
* Handles an encountered JSON Web Token (aka 'JWS') message that has been cryptographically verified/authenticated
* by delegating to either {@link #onVerifiedContent(Jws)} or {@link #onVerifiedClaims(Jws)} depending on the payload
* type.
*
* @param jws the parsed verified/authenticated JWS.
* @return the value returned by either {@link #onVerifiedContent(Jws)} or {@link #onVerifiedClaims(Jws)}
* depending on the payload type.
* @throws UnsupportedJwtException if the payload is neither a {@code byte[]} nor {@code Claims}, or either
* delegate method throws the same.
*/
@SuppressWarnings("unchecked")
@Override
public T visit(Jws<?> jws) {
Assert.notNull(jws, "JWS cannot be null.");
Object payload = jws.getPayload();
if (payload instanceof byte[]) {
return onVerifiedContent((Jws<byte[]>) jws);
} else {
Assert.stateIsInstance(Claims.class, payload, "Unexpected payload data type: ");
return onVerifiedClaims((Jws<Claims>) jws);
}
}
/**
* Handles an encountered JWS message that has been cryptographically verified/authenticated and has
* a byte[] array payload. If the JWT creator has set the (optional) {@link Header#getContentType()} value, the
* application may inspect that value to determine how to convert the byte array to the final type as desired.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jws the parsed verified/authenticated JWS.
* @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onVerifiedContent(Jws<byte[]> jws) {
throw new UnsupportedJwtException("Unexpected content JWS.");
}
/**
* Handles an encountered JWS message that has been cryptographically verified/authenticated and has a
* {@link Claims} payload.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jws the parsed signed (and verified) Claims JWS
* @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onVerifiedClaims(Jws<Claims> jws) {
throw new UnsupportedJwtException("Unexpected Claims JWS.");
}
/**
* Handles an encountered JSON Web Encryption (aka 'JWE') message that has been authenticated and decrypted by
* delegating to either {@link #onDecryptedContent(Jwe)} or {@link #onDecryptedClaims(Jwe)} depending on the
* payload type.
*
* @param jwe the parsed authenticated and decrypted JWE.
* @return the value returned by either {@link #onDecryptedContent(Jwe)} or {@link #onDecryptedClaims(Jwe)}
* depending on the payload type.
* @throws UnsupportedJwtException if the payload is neither a {@code byte[]} nor {@code Claims}, or either
* delegate method throws the same.
*/
@SuppressWarnings("unchecked")
@Override
public T visit(Jwe<?> jwe) {
Assert.notNull(jwe, "JWE cannot be null.");
Object payload = jwe.getPayload();
if (payload instanceof byte[]) {
return onDecryptedContent((Jwe<byte[]>) jwe);
} else {
Assert.stateIsInstance(Claims.class, payload, "Unexpected payload data type: ");
return onDecryptedClaims((Jwe<Claims>) jwe);
}
}
/**
* Handles an encountered JWE message that has been authenticated and decrypted, and has byte[] array payload. If
* the JWT creator has set the (optional) {@link Header#getContentType()} value, the application may inspect that
* value to determine how to convert the byte array to the final type as desired.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jwe the parsed authenticated and decrypted content JWE.
* @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onDecryptedContent(Jwe<byte[]> jwe) {
throw new UnsupportedJwtException("Unexpected content JWE.");
}
/**
* Handles an encountered JWE message that has been authenticated and decrypted, and has a {@link Claims} payload.
*
* <p>The default implementation immediately throws an {@link UnsupportedJwtException}; it is expected that
* subclasses will override this method if the application needs to support this type of JWT.</p>
*
* @param jwe the parsed authenticated and decrypted content JWE.
* @return any object to be used after inspecting the JWE, or {@code null} if no return value is necessary.
* @throws UnsupportedJwtException by default, expecting the subclass implementation to override as necessary.
*/
public T onDecryptedClaims(Jwe<Claims> jwe) {
throw new UnsupportedJwtException("Unexpected Claims JWE.");
}
}

View File

@ -35,6 +35,8 @@ public interface Parser<T> {
T parse(CharSequence input);
/**
* Parse the specified character sequence with the specified bounds into a Java object.
*
* @param input The character sequence, may be {@code null}
* @param start The start index in the character sequence, inclusive
* @param end The end index in the character sequence, exclusive
@ -59,7 +61,6 @@ public interface Parser<T> {
* InputStreamReader}(in, {@link java.nio.charset.StandardCharsets#UTF_8
* StandardCharsets.UTF_8});</pre></blockquote>
*
*
* @param in the UTF-8 InputStream.
* @return the Java object represented by the specified {@link InputStream}.
*/

View File

@ -27,66 +27,66 @@ class JwtHandlerAdapterTest {
@Before
void setUp() {
handler = new JwtHandlerAdapter(){}
handler = new JwtHandlerAdapter() {}
}
@Test
void testOnContentJwt() {
try {
handler.onContentJwt(null)
handler.onUnsecuredContent(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured content JWT.', e.getMessage()
}
}
@Test
void testOnClaimsJwt() {
try {
handler.onClaimsJwt(null)
handler.onUnsecuredClaims(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured Claims JWT.', e.getMessage()
}
}
@Test
void testOnContentJws() {
try {
handler.onContentJws(null)
handler.onVerifiedContent(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Signed content JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected content JWS.', e.getMessage()
}
}
@Test
void testOnClaimsJws() {
try {
handler.onClaimsJws(null)
handler.onVerifiedClaims(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected Claims JWS.', e.getMessage()
}
}
@Test
void testOnContentJwe() {
try {
handler.onContentJwe(null)
handler.onDecryptedContent(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Encrypted content JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected content JWE.', e.getMessage()
}
}
@Test
void testOnClaimsJwe() {
try {
handler.onClaimsJwe(null)
handler.onDecryptedClaims(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Encrypted Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected Claims JWE.', e.getMessage()
}
}
}

View File

@ -17,6 +17,7 @@ package io.jsonwebtoken.impl;
import io.jsonwebtoken.Jwe;
import io.jsonwebtoken.JweHeader;
import io.jsonwebtoken.JwtVisitor;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Objects;
@ -60,4 +61,9 @@ public class DefaultJwe<P> extends DefaultProtectedJwt<JweHeader, P> implements
public int hashCode() {
return Objects.nullSafeHashCode(getHeader(), getPayload(), this.iv, this.digest);
}
@Override
public <T> T accept(JwtVisitor<T> v) {
return v.visit(this);
}
}

View File

@ -17,6 +17,7 @@ package io.jsonwebtoken.impl;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.JwtVisitor;
import io.jsonwebtoken.io.Decoders;
public class DefaultJws<P> extends DefaultProtectedJwt<JwsHeader, P> implements Jws<P> {
@ -35,4 +36,8 @@ public class DefaultJws<P> extends DefaultProtectedJwt<JwsHeader, P> implements
return this.signature;
}
@Override
public <T> T accept(JwtVisitor<T> v) {
return v.visit(this);
}
}

View File

@ -17,6 +17,7 @@ package io.jsonwebtoken.impl;
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;
@ -80,4 +81,9 @@ public class DefaultJwt<H extends Header, P> implements Jwt<H, P> {
public int hashCode() {
return Objects.nullSafeHashCode(header, payload);
}
@Override
public <T> T accept(JwtVisitor<T> v) {
return v.visit(this);
}
}

View File

@ -29,7 +29,6 @@ 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;
@ -162,7 +161,7 @@ public class DefaultJwtParser extends AbstractParser<Jwt<?, ?>> implements JwtPa
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.parseContentJws or JwtParser.parseClaimsJws methods that " +
"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";
private static final String B64_DECOMPRESSION_MSG = "The JWT header references compression algorithm " +
@ -364,8 +363,7 @@ public class DefaultJwtParser extends AbstractParser<Jwt<?, ?>> implements JwtPa
return parse(reader, Payload.EMPTY);
}
private Jwt<?, ?> parse(Reader compact, Payload unencodedPayload)
throws ExpiredJwtException, MalformedJwtException, SignatureException {
private Jwt<?, ?> parse(Reader compact, Payload unencodedPayload) {
Assert.notNull(compact, "Compact reader cannot be null.");
Assert.stateNotNull(unencodedPayload, "internal error: unencodedPayload is null.");
@ -769,113 +767,70 @@ public class DefaultJwtParser extends AbstractParser<Jwt<?, ?>> implements JwtPa
}
}
@SuppressWarnings("deprecation")
@Override
public <T> T parse(CharSequence compact, JwtHandler<T> handler) {
return parse(compact, Payload.EMPTY, handler);
return parse(compact, Payload.EMPTY).accept(handler);
}
private <T> T parse(CharSequence compact, Payload unencodedPayload, JwtHandler<T> handler)
throws ExpiredJwtException, MalformedJwtException, SignatureException {
Assert.notNull(handler, "JwtHandler argument cannot be null.");
private Jwt<?, ?> parse(CharSequence compact, Payload unencodedPayload) {
Assert.hasText(compact, "JWT String argument cannot be null or empty.");
Jwt<?, ?> jwt = parse(new CharSequenceReader(compact), unencodedPayload);
if (jwt instanceof Jws) {
Jws<?> jws = (Jws<?>) jwt;
Object body = jws.getPayload();
if (body instanceof Claims) {
return handler.onClaimsJws((Jws<Claims>) jws);
} else {
return handler.onContentJws((Jws<byte[]>) jws);
}
} else if (jwt instanceof Jwe) {
Jwe<?> jwe = (Jwe<?>) jwt;
Object body = jwe.getPayload();
if (body instanceof Claims) {
return handler.onClaimsJwe((Jwe<Claims>) jwe);
} else {
return handler.onContentJwe((Jwe<byte[]>) jwe);
}
} else {
Object body = jwt.getPayload();
if (body instanceof Claims) {
return handler.onClaimsJwt((Jwt<Header, Claims>) jwt);
} else {
return handler.onContentJwt((Jwt<Header, byte[]>) jwt);
}
}
return parse(new CharSequenceReader(compact), unencodedPayload);
}
@Override
public Jwt<Header, byte[]> parseContentJwt(CharSequence compact) {
return parse(compact, new JwtHandlerAdapter<Jwt<Header, byte[]>>() {
@Override
public Jwt<Header, byte[]> onContentJwt(Jwt<Header, byte[]> jwt) {
return jwt;
}
});
public Jwt<Header, byte[]> parseContentJwt(CharSequence jwt) {
return parse(jwt).accept(Jwt.UNSECURED_CONTENT);
}
@Override
public Jwt<Header, Claims> parseClaimsJwt(CharSequence compact) {
return parse(compact, new JwtHandlerAdapter<Jwt<Header, Claims>>() {
@Override
public Jwt<Header, Claims> onClaimsJwt(Jwt<Header, Claims> jwt) {
return jwt;
}
});
public Jwt<Header, Claims> parseClaimsJwt(CharSequence jwt) {
return parse(jwt).accept(Jwt.UNSECURED_CLAIMS);
}
@Override
public Jws<byte[]> parseContentJws(CharSequence compact) {
return parse(compact, new JwtHandlerAdapter<Jws<byte[]>>() {
@Override
public Jws<byte[]> onContentJws(Jws<byte[]> jws) {
return jws;
}
});
public Jws<byte[]> parseContentJws(CharSequence jws) {
return parseSignedContent(jws);
}
@Override
public Jws<Claims> parseClaimsJws(CharSequence compact) {
return parse(compact, new JwtHandlerAdapter<Jws<Claims>>() {
@Override
public Jws<Claims> onClaimsJws(Jws<Claims> jws) {
return jws;
}
});
public Jws<Claims> parseClaimsJws(CharSequence jws) {
return parseSignedClaims(jws);
}
private Jws<byte[]> parseContentJws(CharSequence jws, Payload unencodedPayload) {
return parse(jws, unencodedPayload, new JwtHandlerAdapter<Jws<byte[]>>() {
@Override
public Jws<byte[]> onContentJws(Jws<byte[]> jws) {
return jws;
}
});
@Override
public Jwt<Header, byte[]> parseUnsecuredContent(CharSequence jwt) throws JwtException, IllegalArgumentException {
return parse(jwt).accept(Jwt.UNSECURED_CONTENT);
}
private Jws<Claims> parseClaimsJws(CharSequence jws, Payload unencodedPayload) {
@Override
public Jwt<Header, Claims> parseUnsecuredClaims(CharSequence jwt) throws JwtException, IllegalArgumentException {
return parse(jwt).accept(Jwt.UNSECURED_CLAIMS);
}
@Override
public Jws<byte[]> parseSignedContent(CharSequence compact) {
return parse(compact).accept(Jws.CONTENT);
}
private Jws<byte[]> parseSignedContent(CharSequence jws, Payload unencodedPayload) {
return parse(jws, unencodedPayload).accept(Jws.CONTENT);
}
@Override
public Jws<Claims> parseSignedClaims(CharSequence compact) {
return parse(compact).accept(Jws.CLAIMS);
}
private Jws<Claims> parseSignedClaims(CharSequence jws, Payload unencodedPayload) {
unencodedPayload.setClaimsExpected(true);
return parse(jws, unencodedPayload, new JwtHandlerAdapter<Jws<Claims>>() {
@Override
public Jws<Claims> onClaimsJws(Jws<Claims> jws) {
return jws;
}
});
return parse(jws, unencodedPayload).accept(Jws.CLAIMS);
}
@Override
public Jws<byte[]> parseContentJws(CharSequence jws, byte[] unencodedPayload) {
public Jws<byte[]> parseSignedContent(CharSequence jws, byte[] unencodedPayload) {
Assert.notEmpty(unencodedPayload, "unencodedPayload argument cannot be null or empty.");
return parseContentJws(jws, new Payload(unencodedPayload, null));
}
@Override
public Jws<Claims> parseClaimsJws(CharSequence jws, byte[] unencodedPayload) {
Assert.notEmpty(unencodedPayload, "unencodedPayload argument cannot be null or empty.");
return parseClaimsJws(jws, new Payload(unencodedPayload, null));
return parseSignedContent(jws, new Payload(unencodedPayload, null));
}
private static Payload payloadFor(InputStream in) {
@ -888,37 +843,33 @@ public class DefaultJwtParser extends AbstractParser<Jwt<?, ?>> implements JwtPa
}
@Override
public Jws<byte[]> parseContentJws(CharSequence jws, InputStream unencodedPayload) {
public Jws<byte[]> parseSignedContent(CharSequence jws, InputStream unencodedPayload) {
Assert.notNull(unencodedPayload, "unencodedPayload InputStream cannot be null.");
return parseContentJws(jws, payloadFor(unencodedPayload));
return parseSignedContent(jws, payloadFor(unencodedPayload));
}
@Override
public Jws<Claims> parseClaimsJws(CharSequence jws, InputStream unencodedPayload) {
public Jws<Claims> parseSignedClaims(CharSequence jws, byte[] unencodedPayload) {
Assert.notEmpty(unencodedPayload, "unencodedPayload argument cannot be null or empty.");
return parseSignedClaims(jws, new Payload(unencodedPayload, null));
}
@Override
public Jws<Claims> 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 parseClaimsJws(jws, new Payload(bytes, null));
return parseSignedClaims(jws, new Payload(bytes, null));
}
@Override
public Jwe<byte[]> parseContentJwe(CharSequence compact) throws JwtException {
return parse(compact, new JwtHandlerAdapter<Jwe<byte[]>>() {
@Override
public Jwe<byte[]> onContentJwe(Jwe<byte[]> jwe) {
return jwe;
}
});
public Jwe<byte[]> parseEncryptedContent(CharSequence compact) throws JwtException {
return parse(compact).accept(Jwe.CONTENT);
}
@Override
public Jwe<Claims> parseClaimsJwe(CharSequence compact) throws JwtException {
return parse(compact, new JwtHandlerAdapter<Jwe<Claims>>() {
@Override
public Jwe<Claims> onClaimsJwe(Jwe<Claims> jwe) {
return jwe;
}
});
public Jwe<Claims> parseEncryptedClaims(CharSequence compact) throws JwtException {
return parse(compact).accept(Jwe.CLAIMS);
}
protected byte[] decode(CharSequence base64UrlEncoded, String name) {

View File

@ -23,13 +23,13 @@ import io.jsonwebtoken.lang.Objects;
import java.security.MessageDigest;
public class DefaultProtectedJwt<H extends ProtectedHeader, P> extends DefaultJwt<H, P> implements ProtectedJwt<H, P> {
abstract class DefaultProtectedJwt<H extends ProtectedHeader, P> extends DefaultJwt<H, P> implements ProtectedJwt<H, P> {
protected final byte[] digest;
private final String digestName;
public DefaultProtectedJwt(H header, P payload, byte[] digest, String digestName) {
protected DefaultProtectedJwt(H header, P payload, byte[] digest, String digestName) {
super(header, payload);
this.digest = Assert.notEmpty(digest, "Digest byte array cannot be null or empty.");
this.digestName = Assert.hasText(digestName, "digestName cannot be null or empty.");

View File

@ -36,13 +36,13 @@ class CustomObjectDeserializationTest {
String jwtString = Jwts.builder().claim("cust", customBean).compact()
// no custom deserialization, object is a map
Jwt<Header, Claims> jwt = Jwts.parser().unsecured().build().parseClaimsJwt(jwtString)
Jwt<Header, Claims> jwt = Jwts.parser().unsecured().build().parseUnsecuredClaims(jwtString)
assertNotNull jwt
assertEquals jwt.getPayload().get('cust'), [key1: 'value1', key2: 42]
// custom type for 'cust' claim
def des = new JacksonDeserializer([cust: CustomBean])
jwt = Jwts.parser().unsecured().json(des).build().parseClaimsJwt(jwtString)
jwt = Jwts.parser().unsecured().json(des).build().parseUnsecuredClaims(jwtString)
assertNotNull jwt
CustomBean result = jwt.getPayload().get("cust", CustomBean)
assertEquals customBean, result

View File

@ -82,10 +82,10 @@ class JwtParserTest {
String bad = base64Url('{"alg":"none"}') + '.' + base64Url(junkPayload) + '.'
try {
Jwts.parser().unsecured().build().parseClaimsJwt(bad)
Jwts.parser().unsecured().build().parseUnsecuredClaims(bad)
fail()
} catch (UnsupportedJwtException expected) {
String msg = 'Unprotected content JWTs are not supported.'
String msg = 'Unexpected unsecured content JWT.'
assertEquals msg, expected.getMessage()
}
}
@ -132,7 +132,7 @@ class JwtParserTest {
}
@Test
void testParseContentJwsWithIncorrectAlg() {
void testParseSignedContentWithIncorrectAlg() {
def header = '{"alg":"none"}'
@ -353,43 +353,43 @@ class JwtParserTest {
}
// ========================================================================
// parseContentJwt tests
// parseUnsecuredContent tests
// ========================================================================
@Test
void testParseContentJwt() {
void testParseUnsecuredContent() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals payload, new String(jwt.payload, StandardCharsets.UTF_8)
}
@Test
void testParseContentJwtWithClaimsJwt() {
void testParseUnprotectedContentWithClaimsJwt() {
String compact = Jwts.builder().setSubject('Joe').compact()
try {
Jwts.parser().unsecured().build().parseContentJwt(compact)
Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unprotected Claims JWTs are not supported.'
assertEquals 'Unexpected unsecured Claims JWT.', e.getMessage()
}
}
@Test
void testParseContentJwtWithContentJws() {
void testParseUnprotectedContentWithContentJws() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, randomKey()).compact()
try {
Jwts.parser().build().parseContentJwt(compact)
Jwts.parser().build().parseUnsecuredContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Cannot verify JWS signature: unable to locate signature verification key for JWS with header: {alg=HS256}', e.getMessage()
@ -397,59 +397,59 @@ class JwtParserTest {
}
@Test
void testParseContentJwtWithClaimsJws() {
void testParseUnsecuredContentWithClaimsJws() {
def key = randomKey()
String compact = Jwts.builder().setSubject('Joe').signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
Jwts.parser().setSigningKey(key).build().parseSignedContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected Claims JWS.', e.getMessage()
}
}
// ========================================================================
// parseClaimsJwt tests
// parseUnsecuredClaims tests
// ========================================================================
@Test
void testParseClaimsJwt() {
void testParseUnsecuredClaims() {
String subject = 'Joe'
String compact = Jwts.builder().setSubject(subject).compact()
Jwt<Header, Claims> jwt = Jwts.parser().unsecured().build().parseClaimsJwt(compact)
Jwt<Header, Claims> jwt = Jwts.parser().unsecured().build().parseUnsecuredClaims(compact)
assertEquals jwt.getPayload().getSubject(), subject
}
@Test
void testParseClaimsJwtWithContentJwt() {
void testParseUnsecuredClaimsWithContentJwt() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).compact()
try {
Jwts.parser().unsecured().build().parseClaimsJwt(compact)
Jwts.parser().unsecured().build().parseUnsecuredClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured content JWT.', e.getMessage()
}
}
@Test
void testParseClaimsJwtWithContentJws() {
void testParseUnsecuredClaimsWithContentJws() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, randomKey()).compact()
try {
Jwts.parser().build().parseClaimsJwt(compact)
Jwts.parser().build().parseUnsecuredClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Cannot verify JWS signature: unable to locate signature verification key for JWS with header: {alg=HS256}', e.getMessage()
@ -457,25 +457,25 @@ class JwtParserTest {
}
@Test
void testParseClaimsJwtWithClaimsJws() {
void testParseUnsecuredClaimsWithClaimsJws() {
def key = randomKey()
String compact = Jwts.builder().setSubject('Joe').signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).build().parseClaimsJwt(compact)
Jwts.parser().setSigningKey(key).build().parseUnsecuredClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected Claims JWS.', e.getMessage()
}
}
// ========================================================================
// parseContentJws tests
// parseSignedContent tests
// ========================================================================
@Test
void testParseContentJws() {
void testParseSignedContent() {
String payload = 'Hello world!'
@ -486,13 +486,13 @@ class JwtParserTest {
def jwt = Jwts.parser().
setSigningKey(key).
build().
parseContentJws(compact)
parseSignedContent(compact)
assertEquals payload, new String(jwt.payload, StandardCharsets.UTF_8)
}
@Test
void testParseContentJwsWithContentJwt() {
void testParseSignedContentWithContentJwt() {
String payload = 'Hello world!'
@ -501,15 +501,15 @@ class JwtParserTest {
String compact = Jwts.builder().setPayload(payload).compact()
try {
Jwts.parser().unsecured().setSigningKey(key).build().parseContentJws(compact)
Jwts.parser().unsecured().setSigningKey(key).build().parseSignedContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured content JWT.', e.getMessage()
}
}
@Test
void testParseContentJwsWithClaimsJwt() {
void testParseSignedContentWithClaimsJwt() {
String subject = 'Joe'
@ -518,15 +518,15 @@ class JwtParserTest {
String compact = Jwts.builder().setSubject(subject).compact()
try {
Jwts.parser().unsecured().setSigningKey(key).build().parseContentJws(compact)
Jwts.parser().unsecured().setSigningKey(key).build().parseSignedContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured Claims JWT.', e.getMessage()
}
}
@Test
void testParseContentJwsWithClaimsJws() {
void testParseSignedContentWithClaimsJws() {
String subject = 'Joe'
@ -535,19 +535,19 @@ class JwtParserTest {
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
Jwts.parser().setSigningKey(key).build().parseSignedContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected Claims JWS.', e.getMessage()
}
}
// ========================================================================
// parseClaimsJws tests
// parseSignedClaims tests
// ========================================================================
@Test
void testParseClaimsJws() {
void testParseSignedClaims() {
String sub = 'Joe'
@ -555,13 +555,13 @@ class JwtParserTest {
String compact = Jwts.builder().setSubject(sub).signWith(SignatureAlgorithm.HS256, key).compact()
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).build().parseSignedClaims(compact)
assertEquals jwt.getPayload().getSubject(), sub
}
@Test
void testParseClaimsJwsWithExpiredJws() {
void testParseSignedClaimsWithExpiredJws() {
long differenceMillis = 843 // arbitrary, anything > 0 is fine
def exp = JwtDateConverter.INSTANCE.applyFrom(System.currentTimeMillis() / 1000L)
@ -572,7 +572,7 @@ class JwtParserTest {
String compact = Jwts.builder().subject(sub).expiration(exp).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).clock(new FixedClock(later)).build().parseClaimsJwt(compact)
Jwts.parser().setSigningKey(key).clock(new FixedClock(later)).build().parseUnsecuredClaims(compact)
fail()
} catch (ExpiredJwtException e) {
def exp8601 = DateFormats.formatIso8601(exp, true)
@ -586,7 +586,7 @@ class JwtParserTest {
}
@Test
void testParseClaimsJwsWithPrematureJws() {
void testParseSignedClaimsWithPrematureJws() {
long differenceMillis = 3842 // arbitrary, anything > 0 is fine
def nbf = JwtDateConverter.INSTANCE.applyFrom(System.currentTimeMillis() / 1000L)
@ -597,7 +597,7 @@ class JwtParserTest {
String compact = Jwts.builder().subject(sub).notBefore(nbf).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).clock(new FixedClock(earlier)).build().parseClaimsJws(compact)
Jwts.parser().setSigningKey(key).clock(new FixedClock(earlier)).build().parseSignedClaims(compact)
fail()
} catch (PrematureJwtException e) {
def nbf8601 = DateFormats.formatIso8601(nbf, true)
@ -612,7 +612,7 @@ class JwtParserTest {
}
@Test
void testParseClaimsJwsWithContentJwt() {
void testParseSignedClaimsWithContentJwt() {
String payload = 'Hello world!'
@ -621,15 +621,15 @@ class JwtParserTest {
String compact = Jwts.builder().setPayload(payload).compact()
try {
Jwts.parser().unsecured().setSigningKey(key).build().parseClaimsJws(compact)
Jwts.parser().unsecured().setSigningKey(key).build().parseSignedClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured content JWT.', e.getMessage()
}
}
@Test
void testParseClaimsJwsWithClaimsJwt() {
void testParseSignedClaimsWithClaimsJwt() {
String subject = 'Joe'
@ -640,15 +640,15 @@ class JwtParserTest {
try {
Jwts.parser().unsecured().setSigningKey(key).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Unprotected Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected unsecured Claims JWT.', e.getMessage()
}
}
@Test
void testParseClaimsJwsWithContentJws() {
void testParseSignedClaimsWithContentJws() {
String subject = 'Joe'
@ -657,15 +657,15 @@ class JwtParserTest {
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
Jwts.parser().setSigningKey(key).build().parseSignedContent(compact)
fail()
} catch (UnsupportedJwtException e) {
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
assertEquals 'Unexpected Claims JWS.', e.getMessage()
}
}
// ========================================================================
// parseClaimsJws with signingKey resolver.
// parseSignedClaims with signingKey resolver.
// ========================================================================
@Test
@ -684,7 +684,7 @@ class JwtParserTest {
}
}
Jws jws = Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
Jws jws = Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseSignedClaims(compact)
assertEquals jws.getPayload().getSubject(), subject
}
@ -706,7 +706,7 @@ class JwtParserTest {
}
try {
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseSignedClaims(compact)
fail()
} catch (SignatureException se) {
assertEquals 'JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.', se.getMessage()
@ -723,7 +723,7 @@ class JwtParserTest {
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKeyResolver(null).build().parseClaimsJws(compact)
Jwts.parser().setSigningKeyResolver(null).build().parseSignedClaims(compact)
fail()
} catch (IllegalArgumentException iae) {
assertEquals 'SigningKeyResolver cannot be null.', iae.getMessage()
@ -742,7 +742,7 @@ class JwtParserTest {
def signingKeyResolver = new SigningKeyResolverAdapter()
try {
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseSignedClaims(compact)
fail()
} catch (UnsupportedJwtException ex) {
assertEquals 'The specified SigningKeyResolver implementation does not support ' +
@ -752,7 +752,7 @@ class JwtParserTest {
}
@Test
void testParseClaimsJwsWithNumericTypes() {
void testParseSignedClaimsWithNumericTypes() {
byte[] key = randomKey()
def b = (byte) 42
@ -770,7 +770,7 @@ class JwtParserTest {
claim("long_big", bigLong).
compact()
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).build().parseSignedClaims(compact)
Claims claims = jwt.getPayload()
@ -782,11 +782,11 @@ class JwtParserTest {
}
// ========================================================================
// parseContentJws with signingKey resolver.
// parseSignedContent with signingKey resolver.
// ========================================================================
@Test
void testParseContentJwsWithSigningKeyResolverAdapter() {
void testParseSignedContentWithSigningKeyResolverAdapter() {
String inputPayload = 'Hello world!'
@ -801,13 +801,13 @@ class JwtParserTest {
}
}
def jws = Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
def jws = Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseSignedContent(compact)
assertEquals inputPayload, new String(jws.payload, StandardCharsets.UTF_8)
}
@Test
void testParseContentJwsWithSigningKeyResolverInvalidKey() {
void testParseSignedContentWithSigningKeyResolverInvalidKey() {
String inputPayload = 'Hello world!'
@ -823,7 +823,7 @@ class JwtParserTest {
}
try {
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseSignedContent(compact)
fail()
} catch (SignatureException se) {
assertEquals 'JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.', se.getMessage()
@ -831,7 +831,7 @@ class JwtParserTest {
}
@Test
void testParseContentJwsWithInvalidSigningKeyResolverAdapter() {
void testParseSignedContentWithInvalidSigningKeyResolverAdapter() {
String payload = 'Hello world!'
@ -842,7 +842,7 @@ class JwtParserTest {
def signingKeyResolver = new SigningKeyResolverAdapter()
try {
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseSignedContent(compact)
fail()
} catch (UnsupportedJwtException ex) {
assertEquals ex.getMessage(), 'The specified SigningKeyResolver implementation does not support content ' +
@ -862,7 +862,7 @@ class JwtParserTest {
try {
// expecting null claim name, but with value
Jwts.parser().setSigningKey(key).require(null, expectedClaimValue).build().parseClaimsJws(compact)
Jwts.parser().setSigningKey(key).require(null, expectedClaimValue).build().parseSignedClaims(compact)
fail()
} catch (IllegalArgumentException e) {
assertEquals(
@ -888,7 +888,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
require("", expectedClaimValue).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IllegalArgumentException e) {
assertEquals(
@ -912,7 +912,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
require(expectedClaimName, null).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IllegalArgumentException e) {
assertEquals(
@ -936,7 +936,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
require(expectedClaimName, expectedClaimValue).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().get(expectedClaimName), expectedClaimValue
}
@ -958,7 +958,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
require(goodClaimName, goodClaimValue).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
assertEquals(
@ -983,7 +983,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
require(claimName, claimValue).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (MissingClaimException e) {
String msg = "Missing '$claimName' claim. Expected value: $claimValue"
@ -1005,7 +1005,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireIssuedAt(issuedAt).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().getIssuedAt().getTime(), truncateMillis(issuedAt), 0
}
@ -1024,7 +1024,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireIssuedAt(goodIssuedAt).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
}
@Test(expected = MissingClaimException)
@ -1040,7 +1040,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireIssuedAt(issuedAt).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
}
@Test
@ -1056,7 +1056,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireIssuer(issuer).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().getIssuer(), issuer
}
@ -1076,7 +1076,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireIssuer(goodIssuer).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
assertEquals(
@ -1100,7 +1100,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireIssuer(issuer).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (MissingClaimException e) {
String msg = "Missing 'iss' claim. Expected value: $issuer"
@ -1121,7 +1121,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireAudience(audience).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals audience, jwt.getPayload().getAudience().iterator().next()
}
@ -1133,7 +1133,7 @@ class JwtParserTest {
def expected = [one, two]
String jwt = Jwts.builder().audience().add(one).add(two).and().compact()
def aud = Jwts.parser().unsecured().requireAudience(one).requireAudience(two).build()
.parseClaimsJwt(jwt).getPayload().getAudience()
.parseUnsecuredClaims(jwt).getPayload().getAudience()
assertEquals expected.size(), aud.size()
assertTrue aud.containsAll(expected)
}
@ -1145,7 +1145,7 @@ class JwtParserTest {
String jwt = Jwts.builder().audience().add(one).add('two').and().compact() // more audiences than required
def aud = Jwts.parser().unsecured().requireAudience(one) // require only one
.build().parseClaimsJwt(jwt).getPayload().getAudience()
.build().parseUnsecuredClaims(jwt).getPayload().getAudience()
assertNotNull aud
assertTrue aud.contains(one)
@ -1157,7 +1157,7 @@ class JwtParserTest {
def two = 'two'
String jwt = Jwts.builder().id('foo').compact()
try {
Jwts.parser().unsecured().requireAudience(one).requireAudience(two).build().parseClaimsJwt(jwt)
Jwts.parser().unsecured().requireAudience(one).requireAudience(two).build().parseUnsecuredClaims(jwt)
fail()
} catch (MissingClaimException expected) {
String msg = "Missing 'aud' claim. Expected values: [$one, $two]"
@ -1172,7 +1172,7 @@ class JwtParserTest {
def expected = [one, two]
String jwt = Jwts.builder().claim('custom', one).compact()
try {
Jwts.parser().unsecured().require('custom', expected).build().parseClaimsJwt(jwt)
Jwts.parser().unsecured().require('custom', expected).build().parseUnsecuredClaims(jwt)
} catch (IncorrectClaimException e) {
String msg = "Missing expected '$two' value in 'custom' claim [$one]."
assertEquals msg, e.message
@ -1194,7 +1194,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireAudience(goodAudience).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
String msg = String.format(MISSING_EXPECTED_CLAIM_VALUE_MESSAGE_TEMPLATE, goodAudience,
@ -1217,7 +1217,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireAudience(audience).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (MissingClaimException e) {
String msg = "Missing 'aud' claim. Expected values: [$audience]"
@ -1238,7 +1238,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireSubject(subject).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().getSubject(), subject
}
@ -1258,7 +1258,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireSubject(goodSubject).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
assertEquals(
@ -1282,7 +1282,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireSubject(subject).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (MissingClaimException e) {
String msg = "Missing 'sub' claim. Expected value: $subject"
@ -1303,7 +1303,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireId(id).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().getId(), id
}
@ -1323,7 +1323,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireId(goodId).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
assertEquals(
@ -1347,7 +1347,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireId(id).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (MissingClaimException e) {
String msg = "Missing 'jti' claim. Expected value: $id"
@ -1369,7 +1369,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireExpiration(expiration).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().getExpiration().getTime(), truncateMillis(expiration)
}
@ -1388,7 +1388,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireExpiration(goodExpiration).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
}
@Test(expected = MissingClaimException)
@ -1404,7 +1404,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireExpiration(expiration).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
}
@Test
@ -1421,7 +1421,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
requireNotBefore(notBefore).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().getNotBefore().getTime(), truncateMillis(notBefore)
}
@ -1440,7 +1440,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireNotBefore(goodNotBefore).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
}
@Test(expected = MissingClaimException)
@ -1456,7 +1456,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
requireNotBefore(notBefore).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
}
@Test
@ -1473,7 +1473,7 @@ class JwtParserTest {
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
require("aDate", aDate).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
assertEquals jwt.getPayload().get("aDate", Date.class), aDate
}
@ -1495,7 +1495,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
require("aDate", goodDate).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
String expected = 'JWT Claim \'aDate\' was expected to be a Date, but its value cannot be converted to a ' +
@ -1520,7 +1520,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
require("aDate", goodDate).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (IncorrectClaimException e) {
assertEquals(
@ -1544,7 +1544,7 @@ class JwtParserTest {
Jwts.parser().setSigningKey(key).
require("aDate", aDate).
build().
parseClaimsJws(compact)
parseSignedClaims(compact)
fail()
} catch (MissingClaimException e) {
String msg = "Missing 'aDate' claim. Expected value: $aDate"

View File

@ -123,7 +123,7 @@ class JwtsTest {
def encodedClaims = base64Url(claimsString)
def compact = encodedHeader + '.' + encodedClaims + '.AAD='
try {
Jwts.parser().build().parseClaimsJws(compact)
Jwts.parser().build().parseSignedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = 'Invalid protected header: Invalid JWS header \'jku\' (JWK Set URL) value: 42. ' +
@ -147,7 +147,7 @@ class JwtsTest {
def sig = Encoders.BASE64URL.encode(result)
def compact = "$h.$c.$sig" as String
try {
Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
Jwts.parser().setSigningKey(key).build().parseSignedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = 'Invalid claims: Invalid JWT Claims \'exp\' (Expiration Time) value: -42-. ' +
@ -172,7 +172,7 @@ class JwtsTest {
String s = 'Hello JJWT'
String cty = 'text/plain'
String compact = Jwts.builder().content(s, cty).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals cty, jwt.header.getContentType()
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
}
@ -183,7 +183,7 @@ class JwtsTest {
byte[] content = Strings.utf8(s)
String cty = 'text/plain'
String compact = Jwts.builder().content(content, cty).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals cty, jwt.header.getContentType()
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
}
@ -194,7 +194,7 @@ class JwtsTest {
InputStream content = new ByteArrayInputStream(Strings.utf8(s))
String cty = 'text/plain'
String compact = Jwts.builder().content(content, cty).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals cty, jwt.header.getContentType()
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
}
@ -204,7 +204,7 @@ class JwtsTest {
String s = 'Hello JJWT'
InputStream content = new ByteArrayInputStream(Strings.utf8(s))
String compact = Jwts.builder().content(content).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertNull jwt.header.getContentType()
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
}
@ -212,7 +212,7 @@ class JwtsTest {
@Test
void testContentStreamNull() {
String compact = Jwts.builder().content((InputStream) null).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals 'none', jwt.header.getAlgorithm()
assertTrue Bytes.isEmpty(jwt.getPayload())
}
@ -223,7 +223,7 @@ class JwtsTest {
String subtype = 'foo'
String cty = "application/$subtype"
String compact = Jwts.builder().content(s, cty).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
// assert raw value is compact form:
assertEquals subtype, jwt.header.get('cty')
// assert getter reflects normalized form per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.10:
@ -237,7 +237,7 @@ class JwtsTest {
String subtype = 'foo'
String cty = "application/$subtype;part=1/2"
String compact = Jwts.builder().content(s, cty).compact()
def jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals cty, jwt.header.getContentType() // two slashes, can't compact
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
}
@ -279,7 +279,7 @@ class JwtsTest {
String claims = Encoders.BASE64URL.encode(claimsJson.getBytes(StandardCharsets.UTF_8))
String compact = header + '.' + claims + '.'
def jwt = Jwts.parser().unsecured().build().parseClaimsJwt(compact)
def jwt = Jwts.parser().unsecured().build().parseUnsecuredClaims(compact)
assertEquals 'none', jwt.header.getAlgorithm()
assertEquals 'joe', jwt.payload.getSubject()
}
@ -344,7 +344,7 @@ class JwtsTest {
int i = compact.lastIndexOf('.')
String missingSig = compact.substring(0, i + 1)
try {
Jwts.parser().unsecured().setSigningKey(key).build().parseClaimsJws(missingSig)
Jwts.parser().unsecured().setSigningKey(key).build().parseSignedClaims(missingSig)
fail()
} catch (MalformedJwtException expected) {
String s = String.format(DefaultJwtParser.MISSING_JWS_DIGEST_MSG_FMT, 'HS256')
@ -484,7 +484,7 @@ class JwtsTest {
String compact = Jwts.builder().id(id).issuer("an issuer").signWith(key, alg)
.claim("state", "hello this is an amazing jwt").compact()
def jws = Jwts.parser().verifyWith(key).build().parseClaimsJws(compact)
def jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(compact)
Claims claims = jws.payload
@ -506,7 +506,7 @@ class JwtsTest {
String compact = Jwts.builder().id(id).issuer("an issuer").signWith(key, alg)
.claim("state", "hello this is an amazing jwt").compressWith(Jwts.ZIP.DEF).compact()
def jws = Jwts.parser().verifyWith(key).build().parseClaimsJws(compact)
def jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(compact)
Claims claims = jws.payload
@ -528,7 +528,7 @@ class JwtsTest {
String compact = Jwts.builder().id(id).issuer("an issuer").signWith(key, alg)
.claim("state", "hello this is an amazing jwt").compressWith(Jwts.ZIP.GZIP).compact()
def jws = Jwts.parser().verifyWith(key).build().parseClaimsJws(compact)
def jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(compact)
Claims claims = jws.payload
@ -566,7 +566,7 @@ class JwtsTest {
return null
}
}
}).build().parseClaimsJws(compact)
}).build().parseSignedClaims(compact)
Claims claims = jws.payload
@ -594,7 +594,7 @@ class JwtsTest {
}
}).compact()
Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
Jwts.parser().setSigningKey(key).build().parseSignedClaims(compact)
}
@Test
@ -608,7 +608,7 @@ class JwtsTest {
String compact = Jwts.builder().setPayload(payload).signWith(key, alg)
.compressWith(Jwts.ZIP.DEF).compact()
def jws = Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
def jws = Jwts.parser().setSigningKey(key).build().parseSignedContent(compact)
assertEquals "DEF", jws.header.getCompressionAlgorithm()
@ -702,7 +702,7 @@ class JwtsTest {
}
@Test(expected = WeakKeyException)
void testParseClaimsJwsWithWeakHmacKey() {
void testparseSignedClaimsWithWeakHmacKey() {
def alg = Jwts.SIG.HS384
def key = alg.key().build()
@ -710,8 +710,8 @@ class JwtsTest {
String jws = Jwts.builder().setSubject("Foo").signWith(key, alg).compact()
Jwts.parser().setSigningKey(weakKey).build().parseClaimsJws(jws)
fail('parseClaimsJws must fail for weak keys')
Jwts.parser().setSigningKey(weakKey).build().parseSignedClaims(jws)
fail('parseSignedClaims must fail for weak keys')
}
/**
@ -756,7 +756,7 @@ class JwtsTest {
def jws = Jwts.builder().setSubject('foo').signWith(pair.private).compact()
def parser = Jwts.parser().setSigningKey(TestKeys.ES384.pair.public).build()
try {
parser.parseClaimsJws(jws)
parser.parseSignedClaims(jws)
} catch (UnsupportedJwtException expected) {
String msg = 'The parsed JWT indicates it was signed with the \'ES256\' signature algorithm, but ' +
'the provided sun.security.ec.ECPublicKeyImpl key may not be used to verify ES256 signatures. ' +
@ -777,12 +777,12 @@ class JwtsTest {
def invalidEncodedSignature = "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ"
String jws = withoutSignature + '.' + invalidEncodedSignature
def keypair = Jwts.SIG.ES256.keyPair().build()
Jwts.parser().setSigningKey(keypair.public).build().parseClaimsJws(jws)
Jwts.parser().setSigningKey(keypair.public).build().parseSignedClaims(jws)
}
//Asserts correct/expected behavior discussed in https://github.com/jwtk/jjwt/issues/20
@Test
void testParseClaimsJwsWithUnsignedJwt() {
void testparseSignedClaimsWithUnsignedJwt() {
//create random signing key for testing:
def alg = Jwts.SIG.HS256
@ -791,10 +791,10 @@ class JwtsTest {
String notSigned = Jwts.builder().setSubject("Foo").compact()
try {
Jwts.parser().unsecured().setSigningKey(key).build().parseClaimsJws(notSigned)
fail('parseClaimsJws must fail for unsigned JWTs')
Jwts.parser().unsecured().setSigningKey(key).build().parseSignedClaims(notSigned)
fail('parseSignedClaims must fail for unsigned JWTs')
} catch (UnsupportedJwtException expected) {
assertEquals 'Unprotected Claims JWTs are not supported.', expected.message
assertEquals 'Unexpected unsecured Claims JWT.', expected.message
}
}
@ -807,7 +807,7 @@ class JwtsTest {
def c = base64Url('{"sub":"joe"}')
def compact = h + '.ecek.iv.' + c + '.tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
assertEquals DefaultJwtParser.MISSING_JWE_ALG_MSG, e.getMessage()
@ -823,7 +823,7 @@ class JwtsTest {
def c = base64Url('{"sub":"joe"}')
def compact = h + '.ecek.iv.' + c + '.tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
assertEquals DefaultJwtParser.MISSING_JWE_ALG_MSG, e.getMessage()
@ -839,7 +839,7 @@ class JwtsTest {
def c = base64Url('{"sub":"joe"}')
def compact = h + '.ecek.iv.' + c + '.tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
assertEquals DefaultJwtParser.MISSING_JWE_ALG_MSG, e.getMessage()
@ -855,7 +855,7 @@ class JwtsTest {
def c = base64Url('{"sub":"joe"}')
def compact = h + '.ecek.iv.' + c + '.tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
assertEquals DefaultJwtParser.JWE_NONE_MSG, e.getMessage()
@ -871,7 +871,7 @@ class JwtsTest {
def c = base64Url('{"sub":"joe"}')
def compact = h + '.ecek.iv.' + c + '.'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = String.format(DefaultJwtParser.MISSING_JWE_DIGEST_MSG_FMT, 'dir')
@ -890,7 +890,7 @@ class JwtsTest {
def tag = '&'
def compact = h + '.IA==.IA==.' + c + '.' + tag
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = 'Compact JWE strings must always contain an AAD Authentication Tag.'
@ -906,7 +906,7 @@ class JwtsTest {
def h = base64Url('{"alg":"dir","enc":"A128GCM"}')
def compact = h + '.ecek.iv..tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = 'Compact JWE strings MUST always contain a payload (ciphertext).'
@ -925,7 +925,7 @@ class JwtsTest {
def encodedKey = '&'
def compact = h + '.' + encodedKey + '.iv.' + c + '.tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = 'Compact JWE string represents an encrypted key, but the key is empty.'
@ -942,7 +942,7 @@ class JwtsTest {
def c = base64Url('{"sub":"joe"}')
def compact = h + '.IA==..' + c + '.tag'
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
String expected = 'Compact JWE strings must always contain an Initialization Vector.'
@ -962,7 +962,7 @@ class JwtsTest {
def tag = 'IA=='
def compact = "$h.$ekey.$iv.$c.$tag" as String
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (MalformedJwtException e) {
assertEquals DefaultJwtParser.MISSING_ENC_MSG, e.getMessage()
@ -981,7 +981,7 @@ class JwtsTest {
def tag = 'IA=='
def compact = "$h.$ekey.$iv.$c.$tag" as String
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
String expected = "Unrecognized JWE 'enc' (Encryption Algorithm) header value: foo"
@ -1001,7 +1001,7 @@ class JwtsTest {
def tag = 'IA=='
def compact = "$h.$ekey.$iv.$c.$tag" as String
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
String expected = "Unrecognized JWE 'alg' (Algorithm) header value: bar"
@ -1019,7 +1019,7 @@ class JwtsTest {
def sig = 'IA=='
def compact = "$h.$c.$sig" as String
try {
Jwts.parser().build().parseClaimsJws(compact)
Jwts.parser().build().parseSignedClaims(compact)
fail()
} catch (io.jsonwebtoken.security.SignatureException e) {
String expected = "Unsupported signature algorithm 'bar'"
@ -1039,7 +1039,7 @@ class JwtsTest {
def tag = 'IA=='
def compact = "$h.$ekey.$iv.$c.$tag" as String
try {
Jwts.parser().build().parseClaimsJwe(compact)
Jwts.parser().build().parseEncryptedClaims(compact)
fail()
} catch (UnsupportedJwtException e) {
String expected = "Cannot decrypt JWE payload: unable to locate key for JWE with header: {alg=dir, enc=A128GCM}"
@ -1063,7 +1063,7 @@ class JwtsTest {
.sig().add(alg).and()
.setSigningKey(key)
.build()
.parseClaimsJws(jws).payload.getSubject()
.parseSignedClaims(jws).payload.getSubject()
}
/**
@ -1107,7 +1107,7 @@ class JwtsTest {
.enc().add(encAlg).and()
.decryptWith(key)
.build()
.parseClaimsJwe(jwe).payload.getSubject()
.parseEncryptedClaims(jwe).payload.getSubject()
}
/**
@ -1145,7 +1145,7 @@ class JwtsTest {
.keyLocator(new ConstantKeyLocator(TestKeys.HS256, TestKeys.A128GCM))
.key().add(badKeyAlg).and() // <-- add bad alg here
.build()
.parseClaimsJwe(compact)
.parseEncryptedClaims(compact)
fail()
} catch (IllegalStateException e) {
String expected = "The 'foo' JWE key algorithm did not return a decryption key. " +
@ -1163,7 +1163,7 @@ class JwtsTest {
def jws = Jwts.builder().signWith(key).claim("foo", 42).compact()
Jwts.parser().setSigningKey(key)
.require("foo", 42L) //require a long, but jws contains int, should still work
.build().parseClaimsJws(jws)
.build().parseSignedClaims(jws)
}
//Asserts correct/expected behavior discussed in https://github.com/jwtk/jjwt/issues/20
@ -1185,7 +1185,7 @@ class JwtsTest {
String forged = Jwts.builder().setSubject("Not Joe").compact()
//assert that our forged header has a 'NONE' algorithm:
assertEquals 'none', Jwts.parser().unsecured().build().parseClaimsJwt(forged).getHeader().get('alg')
assertEquals 'none', Jwts.parser().unsecured().build().parseUnsecuredClaims(forged).getHeader().get('alg')
//now let's forge it by appending the signature the server expects:
forged += signature
@ -1332,7 +1332,7 @@ class JwtsTest {
def jwt = Jwts.parser()
.decryptWith(key)
.build()
.parseClaimsJwe(jwe)
.parseEncryptedClaims(jwe)
assertEquals 'bar', jwt.getPayload().get('foo')
}
}
@ -1360,7 +1360,7 @@ class JwtsTest {
def jwt = Jwts.parser()
.decryptWith(key)
.build()
.parseClaimsJwe(jwe)
.parseEncryptedClaims(jwe)
assertEquals 'bar', jwt.getPayload().get('foo')
}
}
@ -1389,7 +1389,7 @@ class JwtsTest {
def jwt = Jwts.parser()
.decryptWith(key)
.build()
.parseClaimsJwe(jwe)
.parseEncryptedClaims(jwe)
assertEquals 'bar', jwt.getPayload().get('foo')
}
}
@ -1410,7 +1410,7 @@ class JwtsTest {
def jwt = Jwts.parser()
.decryptWith(key)
.build()
.parseClaimsJwe(jwe)
.parseEncryptedClaims(jwe)
assertEquals 'bar', jwt.getPayload().get('foo')
assertEquals Jwts.KEY.PBES2_HS512_A256KW, Jwts.KEY.get().forKey(jwt.getHeader().getAlgorithm())
}
@ -1443,7 +1443,7 @@ class JwtsTest {
def jwt = Jwts.parser()
.decryptWith(privKey)
.build()
.parseClaimsJwe(jwe)
.parseEncryptedClaims(jwe)
assertEquals 'bar', jwt.getPayload().get('foo')
}
}
@ -1478,7 +1478,7 @@ class JwtsTest {
def jwt = Jwts.parser()
.decryptWith(privKey)
.build()
.parseClaimsJwe(jwe)
.parseEncryptedClaims(jwe)
assertEquals 'bar', jwt.getPayload().get('foo')
}
}
@ -1579,7 +1579,7 @@ class JwtsTest {
}
static Jwe<Claims> decrypt(String jwe, PrivateKey key) {
return Jwts.parser().decryptWith(key).build().parseClaimsJwe(jwe)
return Jwts.parser().decryptWith(key).build().parseEncryptedClaims(jwe)
}
static void testRsa(io.jsonwebtoken.security.SignatureAlgorithm alg) {

View File

@ -60,7 +60,7 @@ class RFC7797Test {
}
@Test
void parseContentJwsBytes() {
void parseSignedContentBytes() {
def key = TestKeys.HS256
@ -76,9 +76,9 @@ class RFC7797Test {
def parser = Jwts.parser().verifyWith(key).build()
def jws
if (payload instanceof byte[]) {
jws = parser.parseContentJws(s, (byte[]) payload)
jws = parser.parseSignedContent(s, (byte[]) payload)
} else {
jws = parser.parseContentJws(s, (InputStream) payload)
jws = parser.parseSignedContent(s, (InputStream) payload)
}
// When the supplied unencodedPayload is not a byte array or a ByteArrayInputStream, we can't know how
// big the payload stream might be, and we don't want to pull it all into memory, so the JWS payload
@ -92,7 +92,7 @@ class RFC7797Test {
}
@Test
void parseClaimsJwsBytes() {
void parseSignedClaimsBytes() {
def key = TestKeys.HS256
@ -114,16 +114,16 @@ class RFC7797Test {
def parser = Jwts.parser().verifyWith(key).build()
def jws
if (payload instanceof byte[]) {
jws = parser.parseClaimsJws(s, (byte[]) payload)
jws = parser.parseSignedClaims(s, (byte[]) payload)
} else {
jws = parser.parseClaimsJws(s, (InputStream) payload)
jws = parser.parseSignedClaims(s, (InputStream) payload)
}
assertEquals claims, jws.getPayload()
}
}
@Test
void parseContentJwsByteArrayInputStream() {
void parseSignedContentByteArrayInputStream() {
def key = TestKeys.HS256
@ -140,9 +140,9 @@ class RFC7797Test {
def parser = Jwts.parser().verifyWith(key).build()
def jws
if (payload instanceof byte[]) {
jws = parser.parseContentJws(s, (byte[]) payload)
jws = parser.parseSignedContent(s, (byte[]) payload)
} else {
jws = parser.parseContentJws(s, (InputStream) payload)
jws = parser.parseSignedContent(s, (InputStream) payload)
}
// When the supplied unencodedPayload is not a byte array or a ByteArrayInputStream, we can't know how
// big the payload stream might be, and we don't want to pull it all into memory, so the JWS payload
@ -176,7 +176,7 @@ class RFC7797Test {
String compact = Jwts.builder().content(stream).signWith(key).encodePayload(false).compact()
// signature still verified:
def jwt = Jwts.parser().verifyWith(key).build().parseContentJws(compact, data)
def jwt = Jwts.parser().verifyWith(key).build().parseSignedContent(compact, data)
assertEquals 'HS256', jwt.header.getAlgorithm()
assertEquals s, Strings.utf8(jwt.getPayload())
}
@ -190,7 +190,7 @@ class RFC7797Test {
String s = Jwts.builder().signWith(key).content(payload).encodePayload(false).compact()
def jws = Jwts.parser().verifyWith(key).build().parseClaimsJws(s, payload)
def jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(s, payload)
assertEquals 'me', jws.getPayload().getSubject()
}
@ -211,7 +211,7 @@ class RFC7797Test {
String s = Jwts.builder().signWith(key).content(payload).encodePayload(false).compact()
def jws = Jwts.parser().verifyWith(key) // .critical("b64") is not called, should still work:
.build().parseClaimsJws(s, payload)
.build().parseSignedClaims(s, payload)
assertEquals 'me', jws.getPayload().getSubject()
}
@ -230,7 +230,7 @@ class RFC7797Test {
@Test
void testParseContentWithEmptyBytesPayload() {
try {
Jwts.parser().verifyWith(TestKeys.HS256).build().parseContentJws('whatever', Bytes.EMPTY) // <-- empty
Jwts.parser().verifyWith(TestKeys.HS256).build().parseSignedContent('whatever', Bytes.EMPTY) // <-- empty
fail()
} catch (IllegalArgumentException expected) {
String msg = 'unencodedPayload argument cannot be null or empty.'
@ -241,7 +241,7 @@ class RFC7797Test {
@Test
void testParseClaimsWithEmptyBytesPayload() {
try {
Jwts.parser().verifyWith(TestKeys.HS256).build().parseClaimsJws('whatever', Bytes.EMPTY) // <-- empty
Jwts.parser().verifyWith(TestKeys.HS256).build().parseSignedClaims('whatever', Bytes.EMPTY) // <-- empty
fail()
} catch (IllegalArgumentException expected) {
String msg = 'unencodedPayload argument cannot be null or empty.'
@ -263,7 +263,7 @@ class RFC7797Test {
// try to parse it as a 'normal' JWS (without supplying the payload):
try {
Jwts.parser().verifyWith(key).critical().add(DefaultJwsHeader.B64.id).and().build()
.parseContentJws(s) // <-- no payload supplied
.parseSignedContent(s) // <-- no payload supplied
fail()
} catch (io.jsonwebtoken.security.SignatureException expected) {
String msg = String.format(DefaultJwtParser.B64_MISSING_PAYLOAD, expectedHeader)
@ -286,7 +286,7 @@ class RFC7797Test {
// try to parse it as a 'normal' JWS (without supplying the payload):
try {
Jwts.parser().verifyWith(key).critical().add(DefaultJwsHeader.B64.id).and().build()
.parseClaimsJws(s) // <-- no payload supplied
.parseSignedClaims(s) // <-- no payload supplied
fail()
} catch (io.jsonwebtoken.security.SignatureException expected) {
String msg = String.format(DefaultJwtParser.B64_MISSING_PAYLOAD, expectedHeader)
@ -310,7 +310,7 @@ class RFC7797Test {
String s = Jwts.builder().signWith(key).content(payload).encodePayload(false).compact()
def jws = Jwts.parser().verifyWith(key).critical().add(DefaultJwsHeader.B64.id).and().build()
.parseContentJws(s) // <--- parse normally, without calling parseContentJws(s, unencodedPayload)
.parseSignedContent(s) // <--- parse normally, without calling parseSignedContent(s, unencodedPayload)
assertArrayEquals Strings.utf8(payload), jws.getPayload()
}
@ -324,7 +324,7 @@ class RFC7797Test {
String s = Jwts.builder().signWith(key).subject('me').encodePayload(false).compact()
def jws = Jwts.parser().verifyWith(key).critical().add(DefaultJwsHeader.B64.id).and().build()
.parseClaimsJws(s) // <--- parse normally, without calling parseClaimsJws(s, unencodedPayload)
.parseSignedClaims(s) // <--- parse normally, without calling parseSignedClaims(s, unencodedPayload)
assertEquals 'me', jws.getPayload().getSubject()
}
@ -355,9 +355,9 @@ class RFC7797Test {
def parser = Jwts.parser().verifyWith(key).build()
def jws
if (payload instanceof byte[]) {
jws = parser.parseContentJws(s, (byte[]) payload)
jws = parser.parseSignedContent(s, (byte[]) payload)
} else {
jws = parser.parseContentJws(s, (InputStream) payload)
jws = parser.parseSignedContent(s, (InputStream) payload)
}
// When the supplied unencodedPayload is not a byte array or a ByteArrayInputStream, we can't know how
// big the payload stream might be, and we don't want to pull it all into memory, so the JWS payload
@ -400,7 +400,7 @@ class RFC7797Test {
}
})
.build()
.parseContentJws(s, payload)
.parseSignedContent(s, payload)
fail()
} catch (UnsupportedJwtException expected) {
String msg = String.format(DefaultJwtParser.B64_DECOMPRESSION_MSG, zip.id)

View File

@ -32,7 +32,7 @@ class RsaSigningKeyResolverAdapterTest {
def compact = Jwts.builder().claim('foo', 'bar').signWith(pair.private, alg).compact()
Jws<Claims> jws = Jwts.parser().setSigningKey(pair.public).build().parseClaimsJws(compact)
Jws<Claims> jws = Jwts.parser().setSigningKey(pair.public).build().parseSignedClaims(compact)
try {
new SigningKeyResolverAdapter().resolveSigningKey(jws.header, jws.payload)

View File

@ -30,7 +30,7 @@ class DefaultJweTest {
def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm
def key = alg.key().build()
String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact()
def jwe = Jwts.parser().decryptWith(key).build().parseClaimsJwe(compact)
def jwe = Jwts.parser().decryptWith(key).build().parseEncryptedClaims(compact)
String encodedIv = Encoders.BASE64URL.encode(jwe.initializationVector)
String encodedTag = Encoders.BASE64URL.encode(jwe.digest)
String expected = "header={alg=dir, enc=A128CBC-HS256},payload={foo=bar},tag=$encodedTag,iv=$encodedIv"
@ -43,8 +43,8 @@ class DefaultJweTest {
def key = alg.key().build()
String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact()
def parser = Jwts.parser().decryptWith(key).build()
def jwe1 = parser.parseClaimsJwe(compact)
def jwe2 = parser.parseClaimsJwe(compact)
def jwe1 = parser.parseEncryptedClaims(compact)
def jwe2 = parser.parseEncryptedClaims(compact)
assertNotEquals jwe1, 'hello' as String
assertEquals jwe1, jwe1
assertEquals jwe2, jwe2

View File

@ -40,7 +40,7 @@ class DefaultJwsTest {
String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
int i = compact.lastIndexOf('.')
String signature = compact.substring(i + 1)
def jws = Jwts.parser().verifyWith(key).build().parseClaimsJws(compact)
def jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(compact)
assertEquals 'header={alg=HS256},payload={foo=bar},signature=' + signature, jws.toString()
}
@ -50,8 +50,8 @@ class DefaultJwsTest {
def key = alg.key().build()
String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
def parser = Jwts.parser().verifyWith(key).build()
def jws1 = parser.parseClaimsJws(compact)
def jws2 = parser.parseClaimsJws(compact)
def jws1 = parser.parseSignedClaims(compact)
def jws2 = parser.parseSignedClaims(compact)
assertNotEquals jws1, 'hello' as String
assertEquals jws1, jws1
assertEquals jws2, jws2

View File

@ -339,10 +339,10 @@ class DefaultJwtBuilderTest {
def parser = Jwts.parser().verifyWith(vkey).build()
String s1 = builder.signWith(key).compact()
def jws = parser.parseClaimsJws(s1)
def jws = parser.parseSignedClaims(s1)
String s2 = builder.signWith(key, alg).compact()
def jws2 = parser.parseClaimsJws(s2)
def jws2 = parser.parseSignedClaims(s2)
// signatures differ across duplicate operations for some algorithms, so we can't do
// assertEquals jws, jws2 (since those .equals implementations use the signature)
@ -522,7 +522,7 @@ class DefaultJwtBuilderTest {
.compact()
assertTrue invoked // ensure we call our custom one
assertEquals 'bar', Jwts.parser().setSigningKey(key).build().parseClaimsJws(jws).getPayload().get('foo')
assertEquals 'bar', Jwts.parser().setSigningKey(key).build().parseSignedClaims(jws).getPayload().get('foo')
}
@Test
@ -554,7 +554,7 @@ class DefaultJwtBuilderTest {
def enc = Jwts.ENC.A128GCM
def key = enc.key().build()
def jwe = builder.setPayload("me").encryptWith(key, enc).compact()
def jwt = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe)
def jwt = Jwts.parser().decryptWith(key).build().parseEncryptedContent(jwe)
assertEquals 'me', new String(jwt.getPayload(), StandardCharsets.UTF_8)
}
@ -563,7 +563,7 @@ class DefaultJwtBuilderTest {
def enc = Jwts.ENC.A128GCM
def key = enc.key().build()
def jwe = builder.setSubject('joe').encryptWith(key, enc).compact()
def jwt = Jwts.parser().decryptWith(key).build().parseClaimsJwe(jwe)
def jwt = Jwts.parser().decryptWith(key).build().parseEncryptedClaims(jwe)
assertEquals 'joe', jwt.getPayload().getSubject()
}
@ -637,7 +637,7 @@ class DefaultJwtBuilderTest {
.compact()
// shouldn't be an audience at all:
assertNull Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
assertNull Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
}
/**
@ -655,7 +655,7 @@ class DefaultJwtBuilderTest {
.audience().add([first, second]).and() // sets collection
.compact()
def aud = Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
def aud = Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
assertEquals expected, aud
}
@ -670,7 +670,7 @@ class DefaultJwtBuilderTest {
String audienceSingleString = 'test'
def jwt = builder.audience().single(audienceSingleString).compact()
assertEquals audienceSingleString, Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload
assertEquals audienceSingleString, Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload
.getAudience().iterator().next() // a collection, not a single string
}
@ -678,19 +678,19 @@ class DefaultJwtBuilderTest {
void testAudience() {
def aud = 'fubar'
def jwt = Jwts.builder().audience().add(aud).and().compact()
assertEquals aud, Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience().iterator().next()
assertEquals aud, Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience().iterator().next()
}
@Test
void testAudienceNullString() {
def jwt = Jwts.builder().subject('me').audience().add(null).and().compact()
assertNull Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
assertNull Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
}
@Test
void testAudienceEmptyString() {
def jwt = Jwts.builder().subject('me').audience().add(' ').and().compact()
assertNull Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
assertNull Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
}
@Test
@ -698,7 +698,7 @@ class DefaultJwtBuilderTest {
def one = 'one'
def two = 'two'
def jwt = Jwts.builder().audience().add(one).add(two).and().compact()
def aud = Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
def aud = Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
assertTrue aud.contains(one)
assertTrue aud.contains(two)
}
@ -707,14 +707,14 @@ class DefaultJwtBuilderTest {
void testAudienceNullCollection() {
Collection c = null
def jwt = Jwts.builder().subject('me').audience().add(c).and().compact()
assertNull Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
assertNull Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
}
@Test
void testAudienceEmptyCollection() {
Collection c = new ArrayList()
def jwt = Jwts.builder().subject('me').audience().add(c).and().compact()
assertNull Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
assertNull Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
}
@Test
@ -722,7 +722,7 @@ class DefaultJwtBuilderTest {
Collection c = new ArrayList()
c.add(null)
def jwt = Jwts.builder().subject('me').audience().add(c).and().compact()
assertNull Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
assertNull Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
}
/**
@ -735,7 +735,7 @@ class DefaultJwtBuilderTest {
def two = 'two'
//noinspection GrDeprecatedAPIUsage
def jwt = Jwts.builder().audience().single(one).audience().add(two).and().compact()
def aud = Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
def aud = Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
assertTrue aud.contains(one)
assertTrue aud.contains(two)
}
@ -772,7 +772,7 @@ class DefaultJwtBuilderTest {
def expected = ['one', 'two', 'three'] as Set<String>
//noinspection GrDeprecatedAPIUsage
def jwt = Jwts.builder().audience().single(single).audience().add(collection).and().compact()
def aud = Jwts.parser().unsecured().build().parseClaimsJwt(jwt).payload.getAudience()
def aud = Jwts.parser().unsecured().build().parseUnsecuredClaims(jwt).payload.getAudience()
assertEquals expected.size(), aud.size()
assertTrue aud.contains(single) && aud.containsAll(collection)
}

View File

@ -108,7 +108,7 @@ class DefaultJwtParserBuilderTest {
def parser = builder.base64UrlDecodeWith(decoder).unsecured().build()
assertFalse invoked
assertEquals 'bar', parser.parseClaimsJwt(jwt).getPayload().get('foo')
assertEquals 'bar', parser.parseUnsecuredClaims(jwt).getPayload().get('foo')
assertTrue invoked
}
@ -133,7 +133,7 @@ class DefaultJwtParserBuilderTest {
String jws = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
assertEquals 'bar', p.verifyWith(key).build().parseClaimsJws(jws).getPayload().get('foo')
assertEquals 'bar', p.verifyWith(key).build().parseSignedClaims(jws).getPayload().get('foo')
}
@Test

View File

@ -87,7 +87,7 @@ class DefaultJwtParserTest {
String jws = Jwts.builder().claim('foo', 'bar').signWith(key, Jwts.SIG.HS256).compact()
assertFalse invoked
assertEquals 'bar', pb.verifyWith(key).build().parseClaimsJws(jws).getPayload().get('foo')
assertEquals 'bar', pb.verifyWith(key).build().parseSignedClaims(jws).getPayload().get('foo')
assertTrue invoked
}
@ -106,7 +106,7 @@ class DefaultJwtParserTest {
String invalidJws = compact + encodedSignature
Jwts.parser().verifyWith(key).build().parseClaimsJws(invalidJws)
Jwts.parser().verifyWith(key).build().parseSignedClaims(invalidJws)
}
@Test(expected = MalformedJwtException)
@ -124,7 +124,7 @@ class DefaultJwtParserTest {
String invalidJws = compact + encodedSignature
Jwts.parser().verifyWith(key).build().parseClaimsJwe(invalidJws)
Jwts.parser().verifyWith(key).build().parseEncryptedClaims(invalidJws)
}
@Test(expected = MalformedJwtException)
@ -142,7 +142,7 @@ class DefaultJwtParserTest {
String invalidJws = compact + encodedSignature
Jwts.parser().verifyWith(key).build().parseClaimsJws(invalidJws)
Jwts.parser().verifyWith(key).build().parseSignedClaims(invalidJws)
}
/*
@ -249,7 +249,7 @@ class DefaultJwtParserTest {
.subject('me')
.signWith(key).compact()
def jwt = Jwts.parser().critical().add(crit).and().verifyWith(key).build().parseClaimsJws(jws)
def jwt = Jwts.parser().critical().add(crit).and().verifyWith(key).build().parseSignedClaims(jws)
// no exception thrown, as expected, check the header values:
def parsedCrit = jwt.getHeader().getCritical()
@ -267,7 +267,7 @@ class DefaultJwtParserTest {
def s = Jwts.builder().expiration(exp).compact()
try {
Jwts.parser().unsecured().clock(new FixedClock(later)).build().parseClaimsJwt(s)
Jwts.parser().unsecured().clock(new FixedClock(later)).build().parse(s)
} catch (ExpiredJwtException expected) {
def exp8601 = DateFormats.formatIso8601(exp, true)
def later8601 = DateFormats.formatIso8601(later, true)
@ -286,7 +286,7 @@ class DefaultJwtParserTest {
def s = Jwts.builder().notBefore(nbf).compact()
try {
Jwts.parser().unsecured().clock(new FixedClock(earlier)).build().parseClaimsJwt(s)
Jwts.parser().unsecured().clock(new FixedClock(earlier)).build().parseUnsecuredClaims(s)
} catch (PrematureJwtException expected) {
def nbf8601 = DateFormats.formatIso8601(nbf, true)
def earlier8601 = DateFormats.formatIso8601(earlier, true)
@ -301,11 +301,44 @@ class DefaultJwtParserTest {
def jwt = Encoders.BASE64URL.encode(Strings.utf8('{"alg":"none"}'))
jwt += ".F!3!#." // <-- invalid Base64URL payload
try {
Jwts.parser().unsecured().build().parseClaimsJwt(jwt)
Jwts.parser().unsecured().build().parse(jwt)
fail()
} catch (MalformedJwtException expected) {
String msg = 'Invalid Base64Url payload: <redacted>'
assertEquals msg, expected.message
}
}
@SuppressWarnings('GrDeprecatedAPIUsage')
@Test
void deprecatedAliases() { // TODO: delete this test when deleting these deprecated methods:
// parseContentJwt
byte[] data = Strings.utf8('hello')
def jwt = Jwts.builder().content(data).compact()
assertArrayEquals data, Jwts.parser().unsecured().build().parseContentJwt(jwt).getPayload()
// parseClaimsJwt
jwt = Jwts.builder().subject('me').compact()
assertEquals 'me', Jwts.parser().unsecured().build().parseClaimsJwt(jwt).getPayload().getSubject()
// parseContentJws
def key = TestKeys.HS256
jwt = Jwts.builder().content(data).signWith(key).compact()
assertArrayEquals data, Jwts.parser().verifyWith(key).build().parseContentJws(jwt).getPayload()
// parseClaimsJws
jwt = Jwts.builder().subject('me').signWith(key).compact()
assertEquals 'me', Jwts.parser().verifyWith(key).build().parseClaimsJws(jwt).getPayload().getSubject()
//parse(jwt, handler)
def value = 'foo'
def handler = new JwtHandlerAdapter() {
@Override
Object onClaimsJws(Jws jws) {
return value
}
}
assertEquals value, Jwts.parser().verifyWith(key).build().parse(jwt, handler)
}
}

View File

@ -30,7 +30,7 @@ class DefaultJwtTest {
@Test
void testToString() {
String compact = Jwts.builder().header().add('foo', 'bar').and().audience().add('jsmith').and().compact()
Jwt jwt = Jwts.parser().unsecured().build().parseClaimsJwt(compact)
Jwt jwt = Jwts.parser().unsecured().build().parseUnsecuredClaims(compact)
assertEquals 'header={foo=bar, alg=none},payload={aud=[jsmith]}', jwt.toString()
}
@ -39,7 +39,7 @@ class DefaultJwtTest {
byte[] bytes = 'hello JJWT'.getBytes(StandardCharsets.UTF_8)
String encoded = Encoders.BASE64URL.encode(bytes)
String compact = Jwts.builder().header().add('foo', 'bar').and().content(bytes).compact()
Jwt jwt = Jwts.parser().unsecured().build().parseContentJwt(compact)
Jwt jwt = Jwts.parser().unsecured().build().parseUnsecuredContent(compact)
assertEquals "header={foo=bar, alg=none},payload=$encoded" as String, jwt.toString()
}
@ -47,8 +47,8 @@ class DefaultJwtTest {
void testEqualsAndHashCode() {
String compact = Jwts.builder().claim('foo', 'bar').compact()
def parser = Jwts.parser().unsecured().build()
def jwt1 = parser.parseClaimsJwt(compact)
def jwt2 = parser.parseClaimsJwt(compact)
def jwt1 = parser.parseUnsecuredClaims(compact)
def jwt2 = parser.parseUnsecuredClaims(compact)
assertNotEquals jwt1, 'hello' as String
assertEquals jwt1, jwt1
assertEquals jwt2, jwt2
@ -61,8 +61,8 @@ class DefaultJwtTest {
void testBodyAndPayloadSame() {
String compact = Jwts.builder().claim('foo', 'bar').compact()
def parser = Jwts.parser().unsecured().build()
def jwt1 = parser.parseClaimsJwt(compact)
def jwt2 = parser.parseClaimsJwt(compact)
def jwt1 = parser.parseUnsecuredClaims(compact)
def jwt2 = parser.parseUnsecuredClaims(compact)
assertEquals jwt1.getBody(), jwt1.getPayload()
assertEquals jwt2.getBody(), jwt2.getPayload()
assertEquals jwt1.getBody(), jwt2.getBody()

View File

@ -33,7 +33,7 @@ class DeflateCompressionCodecTest {
@Test
void testBackwardsCompatibility_0_10_6() {
final String jwtFrom0106 = 'eyJhbGciOiJub25lIiwiemlwIjoiREVGIn0.eNqqVsosLlayUspNVdJRKi5NAjJLi1OLgJzMxBIlK0sTMzMLEwsDAx2l1IoCJSsTQwMjExOQQC0AAAD__w.'
Jwts.parser().unsecured().unsecuredDecompression().build().parseClaimsJwt(jwtFrom0106) // no exception should be thrown
Jwts.parser().unsecured().unsecuredDecompression().build().parseUnsecuredClaims(jwtFrom0106) // no exception should be thrown
}
/**

View File

@ -125,7 +125,7 @@ class EdSignatureAlgorithmTest {
static void testSig(PrivateKey signing, PublicKey verification) {
String jwt = Jwts.builder().issuer('me').audience().add('you').and().signWith(signing, alg).compact()
def token = Jwts.parser().verifyWith(verification).build().parseClaimsJws(jwt)
def token = Jwts.parser().verifyWith(verification).build().parseSignedClaims(jwt)
assertEquals([alg: alg.getId()], token.header)
assertEquals 'me', token.getPayload().getIssuer()
assertEquals 'you', token.getPayload().getAudience().iterator().next()

View File

@ -238,7 +238,7 @@ class Pkcs11Test {
} else {
builder.verifyWith(verifyKey as PublicKey)
}
String iss = builder.build().parseClaimsJws(jws).getPayload().getIssuer()
String iss = builder.build().parseSignedClaims(jws).getPayload().getIssuer()
assertEquals 'me', iss
}
@ -278,7 +278,7 @@ class Pkcs11Test {
// Decryption may need private material inside the HSM:
priv = Keys.builder(pair.private).publicKey(pub).provider(provider).build()
String iss = Jwts.parser().decryptWith(priv).build().parseClaimsJwe(jwe).getPayload().getIssuer()
String iss = Jwts.parser().decryptWith(priv).build().parseEncryptedClaims(jwe).getPayload().getIssuer()
assertEquals 'me', iss
}
}

View File

@ -174,7 +174,7 @@ class RFC7516AppendixA1Test {
RsaPrivateJwk jwk = Jwks.builder().add(KEK_VALUES).build() as RsaPrivateJwk
RSAPrivateKey privKey = jwk.toKey()
Jwe<byte[]> jwe = Jwts.parser().decryptWith(privKey).build().parseContentJwe(COMPLETE_JWE)
Jwe<byte[]> jwe = Jwts.parser().decryptWith(privKey).build().parseEncryptedContent(COMPLETE_JWE)
assertEquals PLAINTEXT, new String(jwe.getPayload(), StandardCharsets.UTF_8)
}
}

View File

@ -168,7 +168,7 @@ class RFC7516AppendixA2Test {
RsaPrivateJwk jwk = Jwks.builder().add(KEK_VALUES).build() as RsaPrivateJwk
RSAPrivateKey privKey = jwk.toKey()
Jwe<byte[]> jwe = Jwts.parser().decryptWith(privKey).build().parseContentJwe(COMPLETE_JWE)
Jwe<byte[]> jwe = Jwts.parser().decryptWith(privKey).build().parseEncryptedContent(COMPLETE_JWE)
assertEquals PLAINTEXT, new String(jwe.getPayload(), StandardCharsets.UTF_8)
}
}

View File

@ -106,7 +106,7 @@ class RFC7516AppendixA3Test {
SecretKey kek = jwk.toKey()
// test decryption per the RFC
Jwe<byte[]> jwe = Jwts.parser().decryptWith(kek).build().parseContentJwe(COMPLETE_JWE)
Jwe<byte[]> jwe = Jwts.parser().decryptWith(kek).build().parseEncryptedContent(COMPLETE_JWE)
assertEquals PLAINTEXT, new String(jwe.getPayload(), StandardCharsets.UTF_8)
// now ensure that when JJWT does the encryption (i.e. a compact value is produced from JJWT, not from the RFC text),

View File

@ -330,7 +330,7 @@ class RFC7517AppendixCTest {
assertEquals RFC_COMPACT_JWE, compact
//ensure we can decrypt now:
Jwe<byte[]> jwe = Jwts.parser().decryptWith(key).build().parseContentJwe(compact)
Jwe<byte[]> jwe = Jwts.parser().decryptWith(key).build().parseEncryptedContent(compact)
assertEquals RFC_JWK_JSON, new String(jwe.getPayload(), StandardCharsets.UTF_8)
}

View File

@ -128,7 +128,7 @@ class RFC7518AppendixCTest {
// now reverse the process and ensure it all works:
Jwe<Claims> claimsJwe = Jwts.parser()
.decryptWith(bobJwk.toKey())
.build().parseClaimsJwe(jwe)
.build().parseEncryptedClaims(jwe)
assertEquals RFC_HEADER, claimsJwe.getHeader()
assertEquals "World", claimsJwe.getPayload().get("Hello")

View File

@ -225,7 +225,7 @@ class RFC7520Section4Test {
assertEquals FIGURE_13, result
// Assert round trip works as expected:
def parsed = Jwts.parser().verifyWith(jwk.toPublicJwk().toKey()).build().parseContentJws(result)
def parsed = Jwts.parser().verifyWith(jwk.toPublicJwk().toKey()).build().parseSignedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()
assertEquals FIGURE_7, utf8(parsed.payload)
@ -271,7 +271,7 @@ class RFC7520Section4Test {
// the signature to guarantee a round trip works as expected:
def parsed = Jwts.parser()
.verifyWith(jwk.toPublicJwk().toKey())
.build().parseContentJws(result)
.build().parseSignedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals kid, parsed.header.getKeyId()
@ -316,7 +316,7 @@ class RFC7520Section4Test {
// the signature to guarantee a round trip works as expected:
def parsed = Jwts.parser()
.verifyWith(jwk.toPublicJwk().toKey())
.build().parseContentJws(result)
.build().parseSignedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()
@ -355,7 +355,7 @@ class RFC7520Section4Test {
assertEquals FIGURE_34, result
// Assert round trip works as expected:
def parsed = Jwts.parser().verifyWith(key).build().parseContentJws(result)
def parsed = Jwts.parser().verifyWith(key).build().parseSignedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()
assertEquals FIGURE_7, utf8(parsed.payload)
@ -396,7 +396,7 @@ class RFC7520Section4Test {
assertEquals FIGURE_41, detached
// Assert round trip works as expected:
def parsed = Jwts.parser().verifyWith(key).build().parseContentJws(result)
def parsed = Jwts.parser().verifyWith(key).build().parseSignedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()
assertEquals FIGURE_7, utf8(parsed.payload)

View File

@ -479,7 +479,7 @@ class RFC7520Section5Test {
assertEquals FIGURE_81, result
// Assert round trip works as expected:
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseContentJwe(result)
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseEncryptedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()
assertEquals enc.getId(), parsed.header.getEncryptionAlgorithm()
@ -542,7 +542,7 @@ class RFC7520Section5Test {
assertEquals FIGURE_92, result
// Assert round trip works as expected:
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseContentJwe(result)
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseEncryptedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()
assertEquals enc.getId(), parsed.header.getEncryptionAlgorithm()
@ -602,7 +602,7 @@ class RFC7520Section5Test {
assertEquals FIGURE_105, result
// Assert round trip works as expected:
def parsed = Jwts.parser().decryptWith(key).build().parseContentJwe(result)
def parsed = Jwts.parser().decryptWith(key).build().parseEncryptedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals FIGURE_99, b64Url(parsed.header.getPbes2Salt())
assertEquals p2c, parsed.header.getPbes2Count()
@ -666,7 +666,7 @@ class RFC7520Section5Test {
assertEquals FIGURE_117, result
// Assert round trip works as expected:
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseContentJwe(result)
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseEncryptedContent(result)
assertEquals alg.getId(), parsed.header.getAlgorithm()
assertEquals enc.getId(), parsed.header.getEncryptionAlgorithm()
assertEquals jwk.getId(), parsed.header.getKeyId()

View File

@ -194,7 +194,7 @@ class RFC8037AppendixATest {
assertEquals(rfcExpectedHeaderMap.get('epk'), jweHeaderMap.get('epk'))
//ensure that bob can decrypt:
def jwt = Jwts.parser().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseClaimsJwe(jwe)
def jwt = Jwts.parser().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseEncryptedClaims(jwe)
assertEquals(issuer, jwt.getPayload().getIssuer())
}
@ -285,7 +285,7 @@ class RFC8037AppendixATest {
assertEquals(rfcExpectedHeaderMap.get('epk'), jweHeaderMap.get('epk'))
//ensure that Bob ("Dave") can decrypt:
def jwt = Jwts.parser().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseClaimsJwe(jwe)
def jwt = Jwts.parser().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseEncryptedClaims(jwe)
//assert that we've decrypted and the value in the body/content is as expected:
assertEquals(issuer, jwt.getPayload().getIssuer())

View File

@ -75,7 +75,7 @@ class Issue365Test {
def pair = TestKeys.forAlgorithm(alg).pair
String jws = Jwts.builder().issuer('me').signWith(pair.private).compact()
try {
Jwts.parser().verifyWith(pair.private).build().parseClaimsJws(jws)
Jwts.parser().verifyWith(pair.private).build().parseSignedClaims(jws)
fail()
} catch (IllegalArgumentException expected) {
assertEquals DefaultJwtParser.PRIV_KEY_VERIFY_MSG, expected.getMessage()
@ -95,7 +95,7 @@ class Issue365Test {
return pair.private
}
})
.build().parseClaimsJws(jws)
.build().parseSignedClaims(jws)
fail()
} catch (InvalidKeyException expected) {
assertEquals DefaultJwtParser.PRIV_KEY_VERIFY_MSG, expected.getMessage()
@ -120,7 +120,7 @@ class Issue365Test {
def pub = TestKeys.RS256.pair.public
String jwe = Jwts.builder().issuer('me').encryptWith(pub, Jwts.KEY.RSA1_5, Jwts.ENC.A256GCM).compact()
try {
Jwts.parser().decryptWith(new TestPublicKey()).build().parseClaimsJwe(jwe)
Jwts.parser().decryptWith(new TestPublicKey()).build().parseEncryptedClaims(jwe)
fail()
} catch (IllegalArgumentException expected) {
assertEquals DefaultJwtParser.PUB_KEY_DECRYPT_MSG, expected.getMessage()
@ -138,7 +138,7 @@ class Issue365Test {
return pub
}
})
.build().parseClaimsJwe(jwe)
.build().parseEncryptedClaims(jwe)
fail()
} catch (InvalidKeyException expected) {
assertEquals DefaultJwtParser.PUB_KEY_DECRYPT_MSG, expected.getMessage()

View File

@ -28,6 +28,6 @@ class Issue438Test {
@Test(expected = UnsupportedJwtException /* not IllegalArgumentException */)
void testIssue438() {
String jws = Jwts.builder().issuer('test').signWith(TestKeys.RS256.pair.private).compact()
Jwts.parser().verifyWith(TestKeys.HS256).build().parseClaimsJws(jws)
Jwts.parser().verifyWith(TestKeys.HS256).build().parseSignedClaims(jws)
}
}

View File

@ -42,7 +42,7 @@ class BasicTest {
.setSigningKey(key)
.build()
Jwt<Header, Claims> result = parser.parseClaimsJws(token)
Jwt<Header, Claims> result = parser.parseSignedClaims(token)
assertThat result, notNullValue()
assertThat result.getBody().getSubject(), equalTo("test-user")
assertThat result.getBody().get("test", String), equalTo("basicUsageTest")

View File

@ -76,7 +76,7 @@ public class JavaReadmeTest {
Jws<byte[]> parsed = Jwts.parser().verifyWith(testKey) // 1
.build()
.parseContentJws(jws, content); // 2
.parseSignedContent(jws, content); // 2
assertArrayEquals(content, parsed.getPayload());
}
@ -99,14 +99,14 @@ public class JavaReadmeTest {
Jws<Claims> parsed = Jwts.parser().verifyWith(testKey) // 1
.critical().add("b64").and() // 2
.build()
.parseClaimsJws(jws); // 3
.parseSignedClaims(jws); // 3
assert "joe".equals(parsed.getPayload().getSubject());
assert "me".equals(parsed.getPayload().getIssuer());
parsed = Jwts.parser().verifyWith(testKey)
.build()
.parseClaimsJws(jws, claimsString.getBytes(StandardCharsets.UTF_8)); // <---
.parseSignedClaims(jws, claimsString.getBytes(StandardCharsets.UTF_8)); // <---
assert "joe".equals(parsed.getPayload().getSubject());
assert "me".equals(parsed.getPayload().getIssuer());
@ -128,7 +128,7 @@ public class JavaReadmeTest {
String jws = Jwts.builder().content(content, "text/plain").signWith(key, alg).compact();
// Parse the compact JWS:
content = Jwts.parser().verifyWith(key).build().parseContentJws(jws).getPayload();
content = Jwts.parser().verifyWith(key).build().parseSignedContent(jws).getPayload();
assert message.equals(new String(content, StandardCharsets.UTF_8));
}
@ -150,7 +150,7 @@ public class JavaReadmeTest {
// Alice receives and verifies the compact JWS came from Bob:
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- Bob's RSA public key
.build().parseClaimsJws(jws).getPayload().getSubject();
.build().parseSignedClaims(jws).getPayload().getSubject();
assert "Alice".equals(subject);
}
@ -172,7 +172,7 @@ public class JavaReadmeTest {
// Alice receives and verifies the compact JWS came from Bob:
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- Bob's EC public key
.build().parseClaimsJws(jws).getPayload().getSubject();
.build().parseSignedClaims(jws).getPayload().getSubject();
assert "Alice".equals(subject);
}
@ -194,7 +194,7 @@ public class JavaReadmeTest {
// Alice receives and verifies the compact JWS came from Bob:
String subject = Jwts.parser()
.verifyWith(pair.getPublic()) // <-- Bob's Edwards Curve public key
.build().parseClaimsJws(jws).getPayload().getSubject();
.build().parseSignedClaims(jws).getPayload().getSubject();
assert "Alice".equals(subject);
}
@ -216,7 +216,7 @@ public class JavaReadmeTest {
String jwe = Jwts.builder().content(content, "text/plain").encryptWith(key, enc).compact();
// Parse the compact JWE:
content = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe).getPayload();
content = Jwts.parser().decryptWith(key).build().parseEncryptedContent(jwe).getPayload();
assert message.equals(new String(content, StandardCharsets.UTF_8));
}
@ -242,7 +242,7 @@ public class JavaReadmeTest {
// Alice receives and decrypts the compact JWE:
Set<String> audience = Jwts.parser()
.decryptWith(pair.getPrivate()) // <-- Alice's RSA private key
.build().parseClaimsJwe(jwe).getPayload().getAudience();
.build().parseEncryptedClaims(jwe).getPayload().getAudience();
assert audience.contains("Alice");
}
@ -264,7 +264,7 @@ public class JavaReadmeTest {
// Parse the compact JWE:
String issuer = Jwts.parser().decryptWith(key).build()
.parseClaimsJwe(jwe).getPayload().getIssuer();
.parseEncryptedClaims(jwe).getPayload().getIssuer();
assert "me".equals(issuer);
}
@ -290,7 +290,7 @@ public class JavaReadmeTest {
// Alice receives and decrypts the compact JWE:
Set<String> audience = Jwts.parser()
.decryptWith(pair.getPrivate()) // <-- Alice's EC private key
.build().parseClaimsJwe(jwe).getPayload().getAudience();
.build().parseEncryptedClaims(jwe).getPayload().getAudience();
assert audience.contains("Alice");
}
@ -327,7 +327,7 @@ public class JavaReadmeTest {
// Parse the compact JWE:
String issuer = Jwts.parser().decryptWith(password)
.build().parseClaimsJwe(jwe).getPayload().getIssuer();
.build().parseEncryptedClaims(jwe).getPayload().getIssuer();
assert "me".equals(issuer);
}