mirror of https://github.com/jwtk/jjwt.git
Immutable jwtparser (#791)
* - JwtParser is now immutable (no mutation methods, `final` internal state, etc). - Jwts.parser() has been changed to return a `JwtParserBuilder`, Jwts.parserBuilder() has been removed since it's now superfluous. - LegacyServices.java has been deleted since DefaultJwtParser is no longer mutable (it was used in the parse() method. This logic is now only performed via the Services.java implementation used by the JwtParserBuilder). - ImmutableJwtParser.java has been deleted since it was a wrapper around a mutable DefaultJwtParser implementation. Now that DefaultJwtParser is immutable, ImmutableJwtParser.java is no longer necessary.
This commit is contained in:
parent
529f04dd90
commit
12a4a2e859
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -44,7 +44,7 @@ AeadAlgorithm enc = Jwts.ENC.A256GCM;
|
|||
SecretKey key = enc.keyBuilder().build();
|
||||
String compact = Jwts.builder().setSubject("Joe").encryptWith(key, enc).compact();
|
||||
|
||||
Jwe<Claims> jwe = Jwts.parserBuilder().decryptWith(key).build().parseClaimsJwe(compact);
|
||||
Jwe<Claims> jwe = Jwts.parser().decryptWith(key).build().parseClaimsJwe(compact);
|
||||
```
|
||||
|
||||
Many other RSA and Elliptic Curve examples are in the full README documentation.
|
||||
|
@ -179,8 +179,14 @@ deprecate some concepts, or in some cases, completely break backwards compatibil
|
|||
automatically based on builder state.
|
||||
|
||||
|
||||
* `io.jsonwebtoken.Jwts`'s `parser()` method deprecated 4 years ago has been changed to now return a
|
||||
`JwtParserBuilder` instead of a direct `JwtParser` instance.
|
||||
* `io.jsonwebtoken.JwtParser` is now immutable. All mutation/modification methods (setters, etc) deprecated 4 years
|
||||
ago have been removed. All parser configuration requires using the `JwtParserBuilder` (i.e.
|
||||
`Jwts.parser()`).
|
||||
|
||||
|
||||
* Similarly, `io.jsonwebtoken.Jwts`'s `parser()` method deprecated 4 years ago has been changed to now return a
|
||||
`JwtParserBuilder` instead of a direct `JwtParser` instance. The previous `Jwts.parserBuilder()` method has been
|
||||
removed as it is now redundant.
|
||||
|
||||
|
||||
* `io.jsonwebtoken.CompressionCodec` implementations are no longer discoverable via `java.util.ServiceLoader` due to
|
||||
|
|
80
README.md
80
README.md
|
@ -719,7 +719,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.parserBuilder().verifyWith(key).build().parseClaimsJws(jws).getPayload().getSubject().equals("Joe");
|
||||
assert Jwts.parser().verifyWith(key).build().parseClaimsJws(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
|
||||
|
@ -737,7 +737,7 @@ But what if parsing or signature validation failed? You can catch `JwtException
|
|||
```java
|
||||
try {
|
||||
|
||||
Jwts.parserBuilder().verifyWith(key).build().parseClaimsJws(compactJws);
|
||||
Jwts.parser().verifyWith(key).build().parseClaimsJws(compactJws);
|
||||
|
||||
//OK, we can trust this JWT
|
||||
|
||||
|
@ -957,7 +957,7 @@ String jws = Jwts.builder()
|
|||
.setExpiration(expiration) //a java.util.Date
|
||||
.setNotBefore(notBefore) //a java.util.Date
|
||||
.setIssuedAt(new Date()) // for example, now
|
||||
.setId(UUID.randomUUID()) //just an example id
|
||||
.setId(UUID.randomUUID().toString()) //just an example id
|
||||
|
||||
/// ... etc ...
|
||||
```
|
||||
|
@ -1047,7 +1047,7 @@ Please see the main [Compression](#compression) section to see how to compress a
|
|||
|
||||
You read (parse) a JWT as follows:
|
||||
|
||||
1. Use the `Jwts.parserBuilder()` method to create a `JwtParserBuilder` instance.
|
||||
1. Use the `Jwts.parser()` method to create a `JwtParserBuilder` instance.
|
||||
2. Optionally call `setKeyLocator`, `verifyWith` or `decryptWith` methods if you expect to parse [signed](#jws) or [encrypted](#jwe) JWTs.
|
||||
3. Call the `build()` method on the `JwtParserBuilder` to create and return a thread-safe `JwtParser`.
|
||||
4. Call one of the various `parse*` methods with your compact JWT string, depending on the type of JWT you expect.
|
||||
|
@ -1059,7 +1059,7 @@ For example:
|
|||
Jwt<?,?> jwt;
|
||||
|
||||
try {
|
||||
jwt = Jwts.parserBuilder() // (1)
|
||||
jwt = Jwts.parser() // (1)
|
||||
|
||||
.setKeyLocator(keyLocator) // (2) dynamically locate signing or encryption keys
|
||||
//.verifyWith(key) // or a static key used to verify all signed JWTs
|
||||
|
@ -1099,7 +1099,7 @@ So which key do we use?
|
|||
`JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.verifyWith(secretKey) // <----
|
||||
|
||||
|
@ -1110,7 +1110,7 @@ So which key do we use?
|
|||
`PrivateKey`) should be specified on the `JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.verifyWith(publicKey) // <---- publicKey, not privateKey
|
||||
|
||||
|
@ -1121,7 +1121,7 @@ So which key do we use?
|
|||
specified on the `JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.decryptWith(secretKey) // <----
|
||||
|
||||
|
@ -1132,7 +1132,7 @@ So which key do we use?
|
|||
`PrivateKey` (not the `PublicKey`) should be specified on the `JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.decryptWith(privateKey) // <---- privateKey, not publicKey
|
||||
|
||||
|
@ -1172,7 +1172,7 @@ example:
|
|||
```java
|
||||
Locator<Key> keyLocator = getMyKeyLocator();
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.setKeyLocator(keyLocator) // <----
|
||||
|
||||
|
@ -1214,7 +1214,7 @@ String keyId = getKeyId(key); //any mechanism you have to associate a key with a
|
|||
|
||||
String jws = Jwts.builder()
|
||||
|
||||
.setHeader(Jwts.headerBuilder().setKeyId(keyId)) // <--- add `kid` header
|
||||
.header().setKeyId(keyId).and() // <--- add `kid` header
|
||||
|
||||
.signWith(key) // for JWS
|
||||
//.encryptWith(key, keyAlg, encryptionAlg) // for JWE
|
||||
|
@ -1300,7 +1300,7 @@ otherwise you may not trust the token. You can do that by using one of the vari
|
|||
|
||||
```java
|
||||
try {
|
||||
Jwts.parserBuilder().requireSubject("jsmith")/* etc... */.build().parse(s);
|
||||
Jwts.parser().requireSubject("jsmith")/* etc... */.build().parse(s);
|
||||
} catch (InvalidClaimException ice) {
|
||||
// the sub field was missing or did not have a 'jsmith' value
|
||||
}
|
||||
|
@ -1311,7 +1311,7 @@ you can catch either `MissingClaimException` or `IncorrectClaimException`:
|
|||
|
||||
```java
|
||||
try {
|
||||
Jwts.parserBuilder().requireSubject("jsmith")/* etc... */.build().parse(s);
|
||||
Jwts.parser().requireSubject("jsmith")/* etc... */.build().parse(s);
|
||||
} catch(MissingClaimException mce) {
|
||||
// the parsed JWT did not have the sub field
|
||||
} catch(IncorrectClaimException ice) {
|
||||
|
@ -1323,7 +1323,7 @@ You can also require custom fields by using the `require(fieldName, requiredFiel
|
|||
|
||||
```java
|
||||
try {
|
||||
Jwts.parserBuilder().require("myfield", "myRequiredValue")/* etc... */.build().parse(s);
|
||||
Jwts.parser().require("myfield", "myRequiredValue")/* etc... */.build().parse(s);
|
||||
} catch(InvalidClaimException ice) {
|
||||
// the 'myfield' field was missing or did not have a 'myRequiredValue' value
|
||||
}
|
||||
|
@ -1347,7 +1347,7 @@ You can account for these differences (usually no more than a few minutes) when
|
|||
```java
|
||||
long seconds = 3 * 60; //3 minutes
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.setAllowedClockSkewSeconds(seconds) // <----
|
||||
|
||||
|
@ -1369,7 +1369,7 @@ during parsing for timestamp comparisons can be obtained via a custom time sourc
|
|||
```java
|
||||
Clock clock = new MyClock();
|
||||
|
||||
Jwts.parserBuilder().setClock(myClock) //... etc ...
|
||||
Jwts.parser().setClock(myClock) //... etc ...
|
||||
```
|
||||
|
||||
The `JwtParser`'s default `Clock` implementation simply returns `new Date()` to reflect the time when parsing occurs,
|
||||
|
@ -1692,7 +1692,7 @@ Please see the main [Compression](#compression) section to see how to compress a
|
|||
|
||||
You read (parse) a JWS as follows:
|
||||
|
||||
1. Use the `Jwts.parserBuilder()` method to create a `JwtParserBuilder` instance.
|
||||
1. Use the `Jwts.parser()` method to create a `JwtParserBuilder` instance.
|
||||
2. Call either [setKeyLocator](#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.
|
||||
|
@ -1705,7 +1705,7 @@ For example:
|
|||
Jws<Claims> jws;
|
||||
|
||||
try {
|
||||
jws = Jwts.parserBuilder() // (1)
|
||||
jws = Jwts.parser() // (1)
|
||||
|
||||
.setKeyLocator(keyLocator) // (2) dynamically lookup verification keys based on each JWS
|
||||
//.verifyWith(key) // or a static key used to verify all encountered JWSs
|
||||
|
@ -1740,7 +1740,7 @@ So which key do we use for verification?
|
|||
For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.verifyWith(secretKey) // <----
|
||||
|
||||
|
@ -1751,7 +1751,7 @@ For example:
|
|||
specified on the `JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.verifyWith(publicKey) // <---- publicKey, not privateKey
|
||||
|
||||
|
@ -2166,7 +2166,7 @@ its size. Please see the main [Compression](#compression) section to see how to
|
|||
|
||||
You read (parse) a JWE as follows:
|
||||
|
||||
1. Use the `Jwts.parserBuilder()` method to create a `JwtParserBuilder` instance.
|
||||
1. Use the `Jwts.parser()` method to create a `JwtParserBuilder` instance.
|
||||
2. Call either [setKeyLocator](#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.
|
||||
|
@ -2178,7 +2178,7 @@ For example:
|
|||
Jwe<Claims> jwe;
|
||||
|
||||
try {
|
||||
jwe = Jwts.parserBuilder() // (1)
|
||||
jwe = Jwts.parser() // (1)
|
||||
|
||||
.setKeyLocator(keyLocator) // (2) dynamically lookup decryption keys based on each JWE
|
||||
//.decryptWith(key) // or a static key used to decrypt all encountered JWEs
|
||||
|
@ -2212,7 +2212,7 @@ So which key do we use for decryption?
|
|||
`JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.decryptWith(secretKey) // <----
|
||||
|
||||
|
@ -2223,7 +2223,7 @@ So which key do we use for decryption?
|
|||
`Password` must be specified on the `JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.decryptWith(password) // <---- an `io.jsonwebtoken.security.Password` instance
|
||||
|
||||
|
@ -2234,7 +2234,7 @@ So which key do we use for decryption?
|
|||
the `PublicKey`) must be specified on the `JwtParserBuilder`. For example:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.decryptWith(privateKey) // <---- a `PrivateKey`, not a `PublicKey`
|
||||
|
||||
|
@ -2583,7 +2583,7 @@ by calling the `JwtParserBuilder`'s `addCompressionCodecs` method. For example:
|
|||
```java
|
||||
CompressionCodec myCodec = new MyCompressionCodec();
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.addCompressionCodecs(Collections.of(myCodec)) // <----
|
||||
|
||||
|
@ -2629,7 +2629,7 @@ You then provide your custom `Locator<CompressionCodec>` to the `JwtParserBuilde
|
|||
```java
|
||||
Locator<CompressionCodec> myCodecLocator = new MyCompressionCodecLocator();
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.setCompressionCodecLocator(myCodecLocator) // <----
|
||||
|
||||
|
@ -2694,7 +2694,7 @@ When reading a JWT:
|
|||
```java
|
||||
Deserializer<Map<String,?>> deserializer = getMyDeserializer(); //implement me
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.deserializeJsonWith(deserializer)
|
||||
|
||||
|
@ -2754,7 +2754,7 @@ and the `JacksonDeserializer` using your `ObjectMapper` on the `JwtParserBuilder
|
|||
```java
|
||||
ObjectMapper objectMapper = getMyObjectMapper(); //implement me
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.deserializeJsonWith(new JacksonDeserializer(objectMapper))
|
||||
|
||||
|
@ -2786,7 +2786,7 @@ payload of:
|
|||
The `User` object could be retrieved from the `user` claim with the following code:
|
||||
|
||||
```java
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.deserializeJsonWith(new JacksonDeserializer(Maps.of("user", User.class).build())) // <-----
|
||||
|
||||
|
@ -3027,7 +3027,7 @@ and the `JwtParserBuilder`'s `base64UrlDecodeWith` method to set the decoder:
|
|||
```java
|
||||
Decoder<String, byte[]> base64UrlDecoder = getMyBase64UrlDecoder(); //implement me
|
||||
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
|
||||
.base64UrlDecodeWith(base64UrlEncoder)
|
||||
|
||||
|
@ -3078,7 +3078,7 @@ byte[] content = message.getBytes(StandardCharsets.UTF_8);
|
|||
String jws = Jwts.builder().setContent(content, "text/plain").signWith(key, alg).compact();
|
||||
|
||||
// Parse the compact JWS:
|
||||
content = Jwts.parserBuilder().verifyWith(key).build().parseContentJws(jws).getPayload();
|
||||
content = Jwts.parser().verifyWith(key).build().parseContentJws(jws).getPayload();
|
||||
|
||||
assert message.equals(new String(content, StandardCharsets.UTF_8));
|
||||
```
|
||||
|
@ -3104,7 +3104,7 @@ String jws = Jwts.builder().setSubject("Alice")
|
|||
.compact();
|
||||
|
||||
// Alice receives and verifies the compact JWS came from Bob:
|
||||
String subject = Jwts.parserBuilder()
|
||||
String subject = Jwts.parser()
|
||||
.verifyWith(pair.getPublic()) // <-- Bob's RSA public key
|
||||
.build().parseClaimsJws(jws).getPayload().getSubject();
|
||||
|
||||
|
@ -3135,7 +3135,7 @@ String jws = Jwts.builder().setSubject("Alice")
|
|||
.compact();
|
||||
|
||||
// Alice receives and verifies the compact JWS came from Bob:
|
||||
String subject = Jwts.parserBuilder()
|
||||
String subject = Jwts.parser()
|
||||
.verifyWith(pair.getPublic()) // <-- Bob's EC public key
|
||||
.build().parseClaimsJws(jws).getPayload().getSubject();
|
||||
|
||||
|
@ -3179,7 +3179,7 @@ String jws = Jwts.builder().setSubject("Alice")
|
|||
.compact();
|
||||
|
||||
// Alice receives and verifies the compact JWS came from Bob:
|
||||
String subject = Jwts.parserBuilder()
|
||||
String subject = Jwts.parser()
|
||||
.verifyWith(pair.getPublic()) // <-- Bob's Edwards Curve public key
|
||||
.build().parseClaimsJws(jws).getPayload().getSubject();
|
||||
|
||||
|
@ -3220,7 +3220,7 @@ byte[] content = message.getBytes(StandardCharsets.UTF_8);
|
|||
String jwe = Jwts.builder().setContent(content, "text/plain").encryptWith(key, enc).compact();
|
||||
|
||||
// Parse the compact JWE:
|
||||
content = Jwts.parserBuilder().decryptWith(key).build().parseContentJwe(jwe).getPayload();
|
||||
content = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe).getPayload();
|
||||
|
||||
assert message.equals(new String(content, StandardCharsets.UTF_8));
|
||||
```
|
||||
|
@ -3252,7 +3252,7 @@ String jwe = Jwts.builder().setAudience("Alice")
|
|||
.compact();
|
||||
|
||||
// Alice receives and decrypts the compact JWE:
|
||||
String audience = Jwts.parserBuilder()
|
||||
String audience = Jwts.parser()
|
||||
.decryptWith(pair.getPrivate()) // <-- Alice's RSA private key
|
||||
.build().parseClaimsJwe(jwe).getPayload().getAudience();
|
||||
|
||||
|
@ -3285,7 +3285,7 @@ AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc.
|
|||
String jwe = Jwts.builder().setIssuer("me").encryptWith(key, alg, enc).compact();
|
||||
|
||||
// Parse the compact JWE:
|
||||
String issuer = Jwts.parserBuilder().decryptWith(key).build()
|
||||
String issuer = Jwts.parser().decryptWith(key).build()
|
||||
.parseClaimsJwe(jwe).getPayload().getIssuer();
|
||||
|
||||
assert "me".equals(issuer);
|
||||
|
@ -3320,7 +3320,7 @@ String jwe = Jwts.builder().setAudience("Alice")
|
|||
.compact();
|
||||
|
||||
// Alice receives and decrypts the compact JWE:
|
||||
String audience = Jwts.parserBuilder()
|
||||
String audience = Jwts.parser()
|
||||
.decryptWith(pair.getPrivate()) // <-- Alice's EC private key
|
||||
.build().parseClaimsJwe(jwe).getPayload().getAudience();
|
||||
|
||||
|
@ -3367,7 +3367,7 @@ String jwe = Jwts.builder().setIssuer("me")
|
|||
.compact();
|
||||
|
||||
// Parse the compact JWE:
|
||||
String issuer = Jwts.parserBuilder().decryptWith(password)
|
||||
String issuer = Jwts.parser().decryptWith(password)
|
||||
.build().parseClaimsJwe(jwe).getPayload().getIssuer();
|
||||
|
||||
assert "me".equals(issuer);
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.Collection;
|
|||
* <p>However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you can implement
|
||||
* your own {@link CompressionCodecResolver} and specify that when
|
||||
* {@link io.jsonwebtoken.JwtBuilder#compressWith(io.jsonwebtoken.io.CompressionAlgorithm) building} and
|
||||
* {@link io.jsonwebtoken.JwtParser#setCompressionCodecResolver(CompressionCodecResolver) parsing} JWTs.</p>
|
||||
* {@link io.jsonwebtoken.JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver) parsing} JWTs.</p>
|
||||
*
|
||||
* @see JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver)
|
||||
* @see JwtParserBuilder#addCompressionAlgorithms(Collection)
|
||||
|
|
|
@ -40,7 +40,7 @@ package io.jsonwebtoken;
|
|||
* parameter value.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link io.jsonwebtoken.CompressionCodec CompressionCodec}</td>
|
||||
* <td>{@link io.jsonwebtoken.io.CompressionAlgorithm CompressionAlgorithm}</td>
|
||||
* <td>JWE protected header's
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.3">{@code zip} (Compression Algorithm)</a>
|
||||
* parameter value.</td>
|
||||
|
|
|
@ -15,392 +15,16 @@
|
|||
*/
|
||||
package io.jsonwebtoken;
|
||||
|
||||
import io.jsonwebtoken.io.Decoder;
|
||||
import io.jsonwebtoken.io.Deserializer;
|
||||
import io.jsonwebtoken.security.SecurityException;
|
||||
import io.jsonwebtoken.security.SignatureException;
|
||||
|
||||
import java.security.Key;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT.
|
||||
*
|
||||
* @since 0.1
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
public interface JwtParser {
|
||||
|
||||
/**
|
||||
* Deprecated - this was an implementation detail accidentally added to the public interface. This
|
||||
* will be removed in a future release.
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION, to be removed in a future relase.
|
||||
*/
|
||||
@Deprecated
|
||||
char SEPARATOR_CHAR = '.';
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code jti} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param id the {@code jti} value that must exist in the parsed JWT.
|
||||
* @return the parser method for chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireId(String)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireId(String id);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code sub} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param subject the {@code sub} value that must exist in the parsed JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireSubject(String)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireSubject(String subject);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code aud} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param audience the {@code aud} value that must exist in the parsed JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireAudience(String)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireAudience(String audience);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code iss} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param issuer the {@code iss} value that must exist in the parsed JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireIssuer(String)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireIssuer(String issuer);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code iat} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param issuedAt the {@code iat} value that must exist in the parsed JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireIssuedAt(Date)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireIssuedAt(Date issuedAt);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code exp} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param expiration the {@code exp} value that must exist in the parsed JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireExpiration(Date)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireExpiration(Date expiration);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code nbf} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param notBefore the {@code nbf} value that must exist in the parsed JWT.
|
||||
* @return the parser for method chaining
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#requireNotBefore(Date)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser requireNotBefore(Date notBefore);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code claimName} exists in the parsed JWT. If missing or if the parsed
|
||||
* value does not equal the specified value, an exception will be thrown indicating that the
|
||||
* JWT is invalid and may not be used.
|
||||
*
|
||||
* @param claimName the name of a claim that must exist in the parsed JWT.
|
||||
* @param value the value that must exist for the specified {@code claimName} in the JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @see MissingClaimException
|
||||
* @see IncorrectClaimException
|
||||
* @deprecated see {@link JwtParserBuilder#require(String, Object)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser require(String claimName, Object value);
|
||||
|
||||
/**
|
||||
* Sets the {@link Clock} that determines the timestamp to use when validating the parsed JWT.
|
||||
* The parser uses a default Clock implementation that simply returns {@code new Date()} when called.
|
||||
*
|
||||
* @param clock a {@code Clock} object to return the timestamp to use when validating the parsed JWT.
|
||||
* @return the parser for method chaining.
|
||||
* @since 0.7.0
|
||||
* @deprecated see {@link JwtParserBuilder#setClock(Clock)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser setClock(Clock clock);
|
||||
|
||||
/**
|
||||
* Sets the amount of clock skew in seconds to tolerate when verifying the local time against the {@code exp}
|
||||
* and {@code nbf} claims.
|
||||
*
|
||||
* @param seconds the number of seconds to tolerate for clock skew when verifying {@code exp} or {@code nbf} claims.
|
||||
* @return the parser for method chaining.
|
||||
* @throws IllegalArgumentException if {@code seconds} is a value greater than {@code Long.MAX_VALUE / 1000} as
|
||||
* any such value would cause numeric overflow when multiplying by 1000 to obtain a millisecond value.
|
||||
* @since 0.7.0
|
||||
* @deprecated see {@link JwtParserBuilder#setAllowedClockSkewSeconds(long)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not
|
||||
* a JWS (no signature), this key is not used.
|
||||
*
|
||||
* <p>Note that this key <em>MUST</em> be a valid key for the signature algorithm found in the JWT header
|
||||
* (as the {@code alg} header parameter).</p>
|
||||
*
|
||||
* <p>This method overwrites any previously set key.</p>
|
||||
*
|
||||
* @param key the algorithm-specific signature verification key used to validate any discovered JWS digital
|
||||
* signature.
|
||||
* @return the parser for method chaining.
|
||||
* @deprecated in favor of {@link JwtParserBuilder#verifyWith(Key)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser setSigningKey(byte[] key);
|
||||
|
||||
/**
|
||||
* Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not
|
||||
* a JWS (no signature), this key is not used.
|
||||
*
|
||||
* <p>Note that this key <em>MUST</em> be a valid key for the signature algorithm found in the JWT header
|
||||
* (as the {@code alg} header parameter).</p>
|
||||
*
|
||||
* <p>This method overwrites any previously set key.</p>
|
||||
*
|
||||
* <p>This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting
|
||||
* byte array is used to invoke {@link #setSigningKey(byte[])}.</p>
|
||||
*
|
||||
* <p><b>Deprecation Notice: Deprecated as of 0.10.0, will be removed in 1.0.0</b></p>
|
||||
*
|
||||
* <p>This method has been deprecated because the {@code key} argument for this method can be confusing: keys for
|
||||
* cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were
|
||||
* obtained from the String argument.</p>
|
||||
*
|
||||
* <p>This method always expected a String argument that was effectively the same as the result of the following
|
||||
* (pseudocode):</p>
|
||||
*
|
||||
* <p>{@code String base64EncodedSecretKey = base64Encode(secretKeyBytes);}</p>
|
||||
*
|
||||
* <p>However, a non-trivial number of JJWT users were confused by the method signature and attempted to
|
||||
* use raw password strings as the key argument - for example {@code setSigningKey(myPassword)} - which is
|
||||
* almost always incorrect for cryptographic hashes and can produce erroneous or insecure results.</p>
|
||||
*
|
||||
* <p>See this
|
||||
* <a href="https://stackoverflow.com/questions/40252903/static-secret-as-byte-key-or-string/40274325#40274325">
|
||||
* StackOverflow answer</a> explaining why raw (non-base64-encoded) strings are almost always incorrect for
|
||||
* signature operations.</p>
|
||||
*
|
||||
* <p>Finally, please use the {@link #setSigningKey(Key) setSigningKey(Key)} instead, as this method and the
|
||||
* {@code byte[]} variant will be removed before the 1.0.0 release.</p>
|
||||
*
|
||||
* @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signature verification key to use to validate
|
||||
* any discovered JWS digital signature.
|
||||
* @return the parser for method chaining.
|
||||
* @deprecated in favor of {@link JwtParserBuilder#verifyWith(Key)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser setSigningKey(String base64EncodedSecretKey);
|
||||
|
||||
/**
|
||||
* Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not
|
||||
* a JWS (no signature), this key is not used.
|
||||
*
|
||||
* <p>Note that this key <em>MUST</em> be a valid key for the signature algorithm found in the JWT header
|
||||
* (as the {@code alg} header parameter).</p>
|
||||
*
|
||||
* <p>This method overwrites any previously set key.</p>
|
||||
*
|
||||
* @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital
|
||||
* signature.
|
||||
* @return the parser for method chaining.
|
||||
* @deprecated in favor of {@link JwtParserBuilder#verifyWith(Key)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser setSigningKey(Key key);
|
||||
|
||||
/**
|
||||
* Sets the {@link SigningKeyResolver} used to acquire the <code>signing key</code> that should be used to verify
|
||||
* a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used.
|
||||
*
|
||||
* <p>Specifying a {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing
|
||||
* the JWT and the JWT header or payload (content byte array or Claims) must be inspected first to determine how to
|
||||
* look up the signing key. Once returned by the resolver, the JwtParser will then verify the JWS signature with the
|
||||
* returned key. For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
|
||||
* @Override
|
||||
* public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
|
||||
* //inspect the header or claims, lookup and return the signing key
|
||||
* return getSigningKey(header, claims); //implement me
|
||||
* }})
|
||||
* .parseClaimsJws(compact);
|
||||
* </pre>
|
||||
*
|
||||
* <p>A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.</p>
|
||||
*
|
||||
* <p>This method should only be used if a signing key is not provided by the other {@code setSigningKey*} builder
|
||||
* methods.</p>
|
||||
*
|
||||
* @param signingKeyResolver the signing key resolver used to retrieve the signing key.
|
||||
* @return the parser for method chaining.
|
||||
* @since 0.4
|
||||
* @deprecated in favor of {@link JwtParserBuilder#setKeyLocator(Locator)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
// TODO: remove for 1.0
|
||||
JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver);
|
||||
|
||||
/**
|
||||
* Sets the {@link CompressionCodecResolver} used to acquire the {@link CompressionCodec} that should be used to
|
||||
* decompress the JWT payload. If the parsed JWT is not compressed, this resolver is not used.
|
||||
*
|
||||
* <p><b>NOTE:</b> Compression is not defined by the JWS Specification - only the JWE Specification - and it is
|
||||
* not expected that other libraries (including JJWT versions < 0.6.0) are able to consume a compressed JWS
|
||||
* payload correctly. This method is only useful if the compact JWT was compressed with JJWT >= 0.6.0 or another
|
||||
* library that you know implements the same behavior.</p>
|
||||
*
|
||||
* <p><b>Default Support</b></p>
|
||||
*
|
||||
* <p>JJWT's default {@link JwtParser} implementation supports both the {@link Jwts.ZIP#DEF DEFLATE}
|
||||
* and {@link Jwts.ZIP#GZIP GZIP} algorithms by default - you do not need to
|
||||
* specify a {@code CompressionCodecResolver} in these cases.</p>
|
||||
* <p>However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you may implement
|
||||
* your own {@link CompressionCodecResolver} and specify that via this method and also when
|
||||
* {@link io.jsonwebtoken.JwtBuilder#compressWith(io.jsonwebtoken.io.CompressionAlgorithm) building} JWTs.</p>
|
||||
*
|
||||
* @param compressionCodecResolver the compression codec resolver used to decompress the JWT payload.
|
||||
* @return the parser for method chaining.
|
||||
* @since 0.6.0
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link JwtParserBuilder#addCompressionAlgorithms(Collection)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver);
|
||||
|
||||
/**
|
||||
* Perform Base64Url decoding with the specified Decoder
|
||||
*
|
||||
* <p>JJWT uses a spec-compliant decoder that works on all supported JDK versions, but you may call this method
|
||||
* to specify a different decoder if you desire.</p>
|
||||
*
|
||||
* @param base64UrlDecoder the decoder to use when Base64Url-decoding
|
||||
* @return the parser for method chaining.
|
||||
* @since 0.10.0
|
||||
* @deprecated see {@link JwtParserBuilder#base64UrlDecodeWith(Decoder)}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser base64UrlDecodeWith(Decoder<String, byte[]> base64UrlDecoder);
|
||||
|
||||
/**
|
||||
* Uses the specified deserializer to convert JSON Strings (UTF-8 byte arrays) into Java Map objects. This is
|
||||
* used by the parser after Base64Url-decoding to convert JWT/JWS/JWT JSON headers and claims into Java Map
|
||||
* objects.
|
||||
*
|
||||
* <p>If this method is not called, JJWT will use whatever deserializer it can find at runtime, checking for the
|
||||
* presence of well-known implementations such Jackson, Gson, and org.json. If one of these is not found
|
||||
* in the runtime classpath, an exception will be thrown when one of the various {@code parse}* methods is
|
||||
* invoked.</p>
|
||||
*
|
||||
* @param deserializer the deserializer to use when converting JSON Strings (UTF-8 byte arrays) into Map objects.
|
||||
* @return the parser for method chaining.
|
||||
* @since 0.10.0
|
||||
* @deprecated see {@link JwtParserBuilder#deserializeJsonWith(Deserializer)} )}.
|
||||
* To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an
|
||||
* immutable JwtParser.
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParser deserializeJsonWith(Deserializer<Map<String, ?>> deserializer);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the specified JWT compact string represents a signed JWT (aka a 'JWS'), {@code false}
|
||||
* otherwise.
|
||||
|
@ -455,7 +79,7 @@ public interface JwtParser {
|
|||
* <pre>
|
||||
* String compactJwt = request.getParameter("jwt"); //we are confident this is a signed JWS
|
||||
*
|
||||
* String subject = Jwts.parser().setSigningKey(key).parse(compactJwt, new JwtHandlerAdapter<String>() {
|
||||
* String subject = Jwts.parser().verifyWith(key).build().parse(compactJwt, new JwtHandlerAdapter<String>() {
|
||||
* @Override
|
||||
* public String onClaimsJws(Jws<Claims> jws) {
|
||||
* return jws.getBody().getSubject();
|
||||
|
|
|
@ -32,7 +32,7 @@ import java.util.Map;
|
|||
/**
|
||||
* A builder to construct a {@link JwtParser}. Example usage:
|
||||
* <pre>{@code
|
||||
* Jwts.parserBuilder()
|
||||
* Jwts.parser()
|
||||
* .requireIssuer("https://issuer.example.com")
|
||||
* .verifyWith(...)
|
||||
* .build()
|
||||
|
@ -331,8 +331,9 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
JwtParserBuilder verifyWith(Key key);
|
||||
|
||||
/**
|
||||
* Sets the decryption key to be used to decrypt all encountered JWEs. If the encountered JWT string is not a
|
||||
* JWE (e.g. a JWS), this key is not used.
|
||||
* Sets the decryption key used to decrypt all encountered JWEs, <b>overwriting any previously configured
|
||||
* {@link #setKeyLocator(Locator) keyLocator}</b>. If the encountered JWT string is not a JWE (e.g. a JWS),
|
||||
* this key is not used.
|
||||
*
|
||||
* <p>This is a convenience method to use in specific circumstances: when the parser will only ever encounter
|
||||
* JWEs that can always be decrypted by a single key. This also implies that this key <em>MUST</em> be a valid
|
||||
|
@ -342,7 +343,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* <p>If there is any chance that the parser will encounter JWEs that need different decryption keys based on the
|
||||
* JWE being parsed, or JWSs, it is strongly recommended to configure
|
||||
* your own {@link Locator Locator} via the {@link #setKeyLocator(Locator) setKeyLocator} method instead of
|
||||
* using this one.</p>
|
||||
* using {@code decryptWith}.</p>
|
||||
*
|
||||
* <p>Calling this method overrides any previously set decryption key.</p>
|
||||
*
|
||||
|
@ -366,7 +367,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* verify the JWS signature or decrypt the JWE payload with the returned key. For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* Jws<Claims> jws = Jwts.parserBuilder().setKeyLocator(new Locator<Key>() {
|
||||
* Jws<Claims> jws = Jwts.parser().setKeyLocator(new Locator<Key>() {
|
||||
* @Override
|
||||
* public Key locate(Header<?> header) {
|
||||
* if (header instanceof JwsHeader) {
|
||||
|
@ -412,7 +413,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* //inspect the header or claims, lookup and return the signing key
|
||||
* return getSigningKey(header, claims); //implement me
|
||||
* }})
|
||||
* .parseClaimsJws(compact);
|
||||
* .build().parseClaimsJws(compact);
|
||||
* </pre>
|
||||
*
|
||||
* <p>A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.</p>
|
||||
|
|
|
@ -1056,38 +1056,12 @@ public final class Jwts {
|
|||
return claims().set(claims).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JwtParser} instance that can be configured and then used to parse JWT strings.
|
||||
*
|
||||
* @return a new {@link JwtParser} instance that can be configured and then used to parse JWT strings.
|
||||
* @deprecated use {@link Jwts#parserBuilder()} instead. See {@link JwtParserBuilder} for usage details.
|
||||
* <p>Migration to new method structure is minimal, for example:
|
||||
* <p>Old code:
|
||||
* <pre>{@code
|
||||
* Jwts.parser()
|
||||
* .requireAudience("string")
|
||||
* .parse(jwtString)
|
||||
* }</pre>
|
||||
* <p>New code:
|
||||
* <pre>{@code
|
||||
* Jwts.parserBuilder()
|
||||
* .requireAudience("string")
|
||||
* .build()
|
||||
* .parse(jwtString)
|
||||
* }</pre>
|
||||
* <p><b>NOTE: this method will be removed before version 1.0</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public static JwtParser parser() {
|
||||
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParser");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JwtParserBuilder} instance that can be configured to create an immutable/thread-safe {@link JwtParser}.
|
||||
*
|
||||
* @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser}.
|
||||
*/
|
||||
public static JwtParserBuilder parserBuilder() {
|
||||
public static JwtParserBuilder parser() {
|
||||
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParserBuilder");
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* }})
|
||||
* .parseClaimsJws(compact);
|
||||
* .build().parseClaimsJws(compact);
|
||||
* </pre>
|
||||
*
|
||||
* <p>A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.</p>
|
||||
|
|
|
@ -40,21 +40,17 @@ import io.jsonwebtoken.SigningKeyResolver;
|
|||
import io.jsonwebtoken.UnsupportedJwtException;
|
||||
import io.jsonwebtoken.impl.lang.Bytes;
|
||||
import io.jsonwebtoken.impl.lang.Function;
|
||||
import io.jsonwebtoken.impl.lang.LegacyServices;
|
||||
import io.jsonwebtoken.impl.security.ConstantKeyLocator;
|
||||
import io.jsonwebtoken.impl.security.DefaultAeadResult;
|
||||
import io.jsonwebtoken.impl.security.DefaultDecryptionKeyRequest;
|
||||
import io.jsonwebtoken.impl.security.DefaultVerifySecureDigestRequest;
|
||||
import io.jsonwebtoken.impl.security.LocatingKeyResolver;
|
||||
import io.jsonwebtoken.io.CompressionAlgorithm;
|
||||
import io.jsonwebtoken.io.Decoder;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.io.DecodingException;
|
||||
import io.jsonwebtoken.io.DeserializationException;
|
||||
import io.jsonwebtoken.io.Deserializer;
|
||||
import io.jsonwebtoken.lang.Arrays;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import io.jsonwebtoken.lang.Collections;
|
||||
import io.jsonwebtoken.lang.DateFormats;
|
||||
import io.jsonwebtoken.lang.Strings;
|
||||
import io.jsonwebtoken.security.AeadAlgorithm;
|
||||
|
@ -62,7 +58,6 @@ import io.jsonwebtoken.security.DecryptAeadRequest;
|
|||
import io.jsonwebtoken.security.DecryptionKeyRequest;
|
||||
import io.jsonwebtoken.security.InvalidKeyException;
|
||||
import io.jsonwebtoken.security.KeyAlgorithm;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import io.jsonwebtoken.security.Message;
|
||||
import io.jsonwebtoken.security.SecureDigestAlgorithm;
|
||||
import io.jsonwebtoken.security.SignatureException;
|
||||
|
@ -82,8 +77,6 @@ public class DefaultJwtParser implements JwtParser {
|
|||
|
||||
static final char SEPARATOR_CHAR = '.';
|
||||
|
||||
private static final int MILLISECONDS_PER_SECOND = 1000;
|
||||
|
||||
private static final JwtTokenizer jwtTokenizer = new JwtTokenizer();
|
||||
|
||||
public static final String INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE = "Expected %s claim to be: %s, but was: %s.";
|
||||
|
@ -131,68 +124,34 @@ public class DefaultJwtParser implements JwtParser {
|
|||
"enableUnsecuredDecompression() method (but please read the security considerations covered in that " +
|
||||
"method's JavaDoc before doing so).";
|
||||
|
||||
private static Function<JwsHeader, SecureDigestAlgorithm<?, ?>> sigFn(Collection<SecureDigestAlgorithm<?, ?>> extras) {
|
||||
return new IdLocator<>(DefaultHeader.ALGORITHM, Jwts.SIG.get(), extras, MISSING_JWS_ALG_MSG);
|
||||
}
|
||||
private final Provider provider;
|
||||
|
||||
private static Function<JweHeader, AeadAlgorithm> encFn(Collection<AeadAlgorithm> extras) {
|
||||
return new IdLocator<>(DefaultJweHeader.ENCRYPTION_ALGORITHM, Jwts.ENC.get(), extras, MISSING_ENC_MSG);
|
||||
}
|
||||
|
||||
private static Function<JweHeader, KeyAlgorithm<?, ?>> keyFn(Collection<KeyAlgorithm<?, ?>> extras) {
|
||||
return new IdLocator<>(DefaultHeader.ALGORITHM, Jwts.KEY.get(), extras, MISSING_JWE_ALG_MSG);
|
||||
}
|
||||
|
||||
private static IdLocator<Header, CompressionAlgorithm> zipFn(Collection<CompressionAlgorithm> extras) {
|
||||
return new IdLocator<>(DefaultHeader.COMPRESSION_ALGORITHM, Jwts.ZIP.get(), extras, null);
|
||||
}
|
||||
|
||||
// TODO: make the following fields final for v1.0
|
||||
private Provider provider;
|
||||
|
||||
@SuppressWarnings("deprecation") // will remove for 1.0
|
||||
private SigningKeyResolver signingKeyResolver;
|
||||
@SuppressWarnings("deprecation")
|
||||
private final SigningKeyResolver signingKeyResolver;
|
||||
|
||||
private final boolean enableUnsecuredJws;
|
||||
|
||||
private final boolean enableUnsecuredDecompression;
|
||||
|
||||
private final Function<JwsHeader, SecureDigestAlgorithm<?, ?>> signatureAlgorithmLocator;
|
||||
private final Function<JwsHeader, SecureDigestAlgorithm<?, ?>> sigAlgFn;
|
||||
|
||||
private final Function<JweHeader, AeadAlgorithm> encryptionAlgorithmLocator;
|
||||
private final Function<JweHeader, AeadAlgorithm> encAlgFn;
|
||||
|
||||
private final Function<JweHeader, KeyAlgorithm<?, ?>> keyAlgorithmLocator;
|
||||
private final Function<JweHeader, KeyAlgorithm<?, ?>> keyAlgFn;
|
||||
|
||||
private Function<Header, CompressionAlgorithm> compressionAlgorithmLocator;
|
||||
private final Function<Header, CompressionAlgorithm> zipAlgFn;
|
||||
|
||||
private final Locator<? extends Key> keyLocator;
|
||||
|
||||
private Decoder<String, byte[]> base64UrlDecoder = Decoders.BASE64URL;
|
||||
private final Decoder<String, byte[]> base64UrlDecoder;
|
||||
|
||||
private Deserializer<Map<String, ?>> deserializer;
|
||||
private final Deserializer<Map<String, ?>> deserializer;
|
||||
|
||||
private ClaimsBuilder expectedClaims = Jwts.claims();
|
||||
private final ClaimsBuilder expectedClaims;
|
||||
|
||||
private Clock clock = DefaultClock.INSTANCE;
|
||||
private final Clock clock;
|
||||
|
||||
private long allowedClockSkewMillis = 0;
|
||||
|
||||
/**
|
||||
* TODO: remove this constructor before 1.0
|
||||
*
|
||||
* @deprecated for backward compatibility only, see other constructors.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed") // will remove before 1.0
|
||||
@Deprecated
|
||||
public DefaultJwtParser() {
|
||||
this.keyLocator = new ConstantKeyLocator(null, null);
|
||||
this.signatureAlgorithmLocator = sigFn(Collections.<SecureDigestAlgorithm<?, ?>>emptyList());
|
||||
this.keyAlgorithmLocator = keyFn(Collections.<KeyAlgorithm<?, ?>>emptyList());
|
||||
this.encryptionAlgorithmLocator = encFn(Collections.<AeadAlgorithm>emptyList());
|
||||
this.compressionAlgorithmLocator = zipFn(Collections.<CompressionAlgorithm>emptyList());
|
||||
this.enableUnsecuredJws = false;
|
||||
this.enableUnsecuredDecompression = false;
|
||||
}
|
||||
private final long allowedClockSkewMillis;
|
||||
|
||||
//SigningKeyResolver will be removed for 1.0:
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -216,134 +175,17 @@ public class DefaultJwtParser implements JwtParser {
|
|||
this.enableUnsecuredDecompression = enableUnsecuredDecompression;
|
||||
this.signingKeyResolver = signingKeyResolver;
|
||||
this.keyLocator = Assert.notNull(keyLocator, "Key Locator cannot be null.");
|
||||
this.clock = clock;
|
||||
this.clock = Assert.notNull(clock, "Clock cannot be null.");
|
||||
this.allowedClockSkewMillis = allowedClockSkewMillis;
|
||||
this.expectedClaims = Jwts.claims().set(expectedClaims);
|
||||
this.base64UrlDecoder = base64UrlDecoder;
|
||||
this.deserializer = deserializer;
|
||||
this.signatureAlgorithmLocator = sigFn(extraSigAlgs);
|
||||
this.keyAlgorithmLocator = keyFn(extraKeyAlgs);
|
||||
this.encryptionAlgorithmLocator = encFn(extraEncAlgs);
|
||||
this.base64UrlDecoder = Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null.");
|
||||
this.deserializer = Assert.notNull(deserializer, "Deserializer cannot be null.");
|
||||
|
||||
if (compressionCodecResolver != null) {
|
||||
this.compressionAlgorithmLocator = new CompressionCodecLocator(compressionCodecResolver);
|
||||
} else {
|
||||
this.compressionAlgorithmLocator = zipFn(extraZipAlgs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser deserializeJsonWith(Deserializer<Map<String, ?>> deserializer) {
|
||||
Assert.notNull(deserializer, "deserializer cannot be null.");
|
||||
this.deserializer = new JwtDeserializer<>(deserializer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser base64UrlDecodeWith(Decoder<String, byte[]> base64UrlDecoder) {
|
||||
Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null.");
|
||||
this.base64UrlDecoder = base64UrlDecoder;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireIssuedAt(Date issuedAt) {
|
||||
expectedClaims.setIssuedAt(issuedAt);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireIssuer(String issuer) {
|
||||
expectedClaims.setIssuer(issuer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireAudience(String audience) {
|
||||
expectedClaims.setAudience(audience);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireSubject(String subject) {
|
||||
expectedClaims.setSubject(subject);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireId(String id) {
|
||||
expectedClaims.setId(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireExpiration(Date expiration) {
|
||||
expectedClaims.setExpiration(expiration);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireNotBefore(Date notBefore) {
|
||||
expectedClaims.setNotBefore(notBefore);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser require(String claimName, Object value) {
|
||||
Assert.hasText(claimName, "claim name cannot be null or empty.");
|
||||
Assert.notNull(value, "The value cannot be null for claim name: " + claimName);
|
||||
expectedClaims.set(claimName, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setClock(Clock clock) {
|
||||
Assert.notNull(clock, "Clock instance cannot be null.");
|
||||
this.clock = clock;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException {
|
||||
Assert.isTrue(seconds <= DefaultJwtParserBuilder.MAX_CLOCK_SKEW_MILLIS, DefaultJwtParserBuilder.MAX_CLOCK_SKEW_ILLEGAL_MSG);
|
||||
this.allowedClockSkewMillis = Math.max(0, seconds * MILLISECONDS_PER_SECOND);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKey(byte[] key) {
|
||||
Assert.notEmpty(key, "signing key cannot be null or empty.");
|
||||
return setSigningKey(Keys.hmacShaKeyFor(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKey(String base64EncodedSecretKey) {
|
||||
Assert.hasText(base64EncodedSecretKey, "signing key cannot be null or empty.");
|
||||
byte[] bytes = Decoders.BASE64.decode(base64EncodedSecretKey);
|
||||
return setSigningKey(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKey(final Key key) {
|
||||
Assert.notNull(key, "signing key cannot be null.");
|
||||
setSigningKeyResolver(new ConstantKeyLocator(key, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // required until 1.0
|
||||
@Override
|
||||
public JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver) {
|
||||
Assert.notNull(signingKeyResolver, "SigningKeyResolver cannot be null.");
|
||||
this.signingKeyResolver = signingKeyResolver;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public JwtParser setCompressionCodecResolver(CompressionCodecResolver resolver) {
|
||||
Assert.notNull(resolver, "CompressionCodecResolver cannot be null.");
|
||||
this.compressionAlgorithmLocator = new CompressionCodecLocator(resolver);
|
||||
return this;
|
||||
this.sigAlgFn = new IdLocator<>(DefaultHeader.ALGORITHM, Jwts.SIG.get(), extraSigAlgs, MISSING_JWS_ALG_MSG);
|
||||
this.keyAlgFn = new IdLocator<>(DefaultHeader.ALGORITHM, Jwts.KEY.get(), extraKeyAlgs, MISSING_JWE_ALG_MSG);
|
||||
this.encAlgFn = new IdLocator<>(DefaultJweHeader.ENCRYPTION_ALGORITHM, Jwts.ENC.get(), extraEncAlgs, MISSING_ENC_MSG);
|
||||
this.zipAlgFn = compressionCodecResolver != null ? new CompressionCodecLocator(compressionCodecResolver) :
|
||||
new IdLocator<>(DefaultHeader.COMPRESSION_ALGORITHM, Jwts.ZIP.get(), extraZipAlgs, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -442,7 +284,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
|
||||
SecureDigestAlgorithm<?, Key> algorithm;
|
||||
try {
|
||||
algorithm = (SecureDigestAlgorithm<?, Key>) signatureAlgorithmLocator.apply(jwsHeader);
|
||||
algorithm = (SecureDigestAlgorithm<?, Key>) sigAlgFn.apply(jwsHeader);
|
||||
} catch (UnsupportedJwtException e) {
|
||||
//For backwards compatibility. TODO: remove this try/catch block for 1.0 and let UnsupportedJwtException propagate
|
||||
String msg = "Unsupported signature algorithm '" + alg + "'";
|
||||
|
@ -494,15 +336,6 @@ public class DefaultJwtParser implements JwtParser {
|
|||
@Override
|
||||
public Jwt<?, ?> parse(String compact) throws ExpiredJwtException, MalformedJwtException, SignatureException {
|
||||
|
||||
// TODO, this logic is only need for a now deprecated code path
|
||||
// remove this block in v1.0 (the equivalent is already in DefaultJwtParserBuilder)
|
||||
if (this.deserializer == null) {
|
||||
// try to find one based on the services available
|
||||
// TODO: This util class will throw a UnavailableImplementationException here to retain behavior of previous version, remove in v1.0
|
||||
//noinspection deprecation
|
||||
this.deserializer = LegacyServices.loadFirst(Deserializer.class);
|
||||
}
|
||||
|
||||
Assert.hasText(compact, "JWT String cannot be null or empty.");
|
||||
|
||||
final TokenizedJwt tokenized = jwtTokenizer.tokenize(compact);
|
||||
|
@ -607,10 +440,10 @@ public class DefaultJwtParser implements JwtParser {
|
|||
if (!Strings.hasText(enc)) {
|
||||
throw new MalformedJwtException(MISSING_ENC_MSG);
|
||||
}
|
||||
final AeadAlgorithm encAlg = this.encryptionAlgorithmLocator.apply(jweHeader);
|
||||
final AeadAlgorithm encAlg = this.encAlgFn.apply(jweHeader);
|
||||
Assert.stateNotNull(encAlg, "JWE Encryption Algorithm cannot be null.");
|
||||
|
||||
@SuppressWarnings("rawtypes") final KeyAlgorithm keyAlg = this.keyAlgorithmLocator.apply(jweHeader);
|
||||
@SuppressWarnings("rawtypes") final KeyAlgorithm keyAlg = this.keyAlgFn.apply(jweHeader);
|
||||
Assert.stateNotNull(keyAlg, "JWE Key Algorithm cannot be null.");
|
||||
|
||||
final Key key = this.keyLocator.locate(jweHeader);
|
||||
|
@ -639,7 +472,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
verifySignature(tokenized, ((JwsHeader) header), alg, new LocatingKeyResolver(this.keyLocator), null, null);
|
||||
}
|
||||
|
||||
CompressionAlgorithm compressionAlgorithm = compressionAlgorithmLocator.apply(header);
|
||||
CompressionAlgorithm compressionAlgorithm = zipAlgFn.apply(header);
|
||||
if (compressionAlgorithm != null) {
|
||||
if (unsecured && !enableUnsecuredDecompression) {
|
||||
String msg = String.format(UNPROTECTED_DECOMPRESSION_MSG, compressionAlgorithm.getId());
|
||||
|
|
|
@ -282,16 +282,26 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
}
|
||||
|
||||
if (this.signingKeyResolver != null && this.signatureVerificationKey != null) {
|
||||
String msg = "Both 'signingKeyResolver and 'verifyWith/signWith' key cannot be configured. " +
|
||||
String msg = "Both a 'signingKeyResolver and a 'verifyWith' key cannot be configured. " +
|
||||
"Choose either, or prefer `keyLocator` when possible.";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
if (this.keyLocator != null && this.decryptionKey != null) {
|
||||
String msg = "Both 'keyLocator' and 'decryptWith' key cannot be configured. Prefer 'keyLocator' if possible.";
|
||||
if (this.keyLocator != null) {
|
||||
if (this.signatureVerificationKey != null) {
|
||||
String msg = "Both 'keyLocator' and a 'verifyWith' key cannot be configured. " +
|
||||
"Prefer 'keyLocator' if possible.";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
if (this.keyLocator == null) {
|
||||
this.keyLocator = new ConstantKeyLocator(this.signatureVerificationKey, this.decryptionKey);
|
||||
if (this.decryptionKey != null) {
|
||||
String msg = "Both 'keyLocator' and a 'decryptWith' key cannot be configured. " +
|
||||
"Prefer 'keyLocator' if possible.";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Locator<? extends Key> keyLocator = this.keyLocator; // user configured default, don't overwrite to ensure further build() calls work as expected
|
||||
if (keyLocator == null) {
|
||||
keyLocator = new ConstantKeyLocator(this.signatureVerificationKey, this.decryptionKey);
|
||||
}
|
||||
|
||||
if (!enableUnsecuredJws && enableUnsecuredDecompression) {
|
||||
|
@ -306,13 +316,12 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
throw new IllegalStateException(msg);
|
||||
}
|
||||
|
||||
// Invariants. If these are ever violated, it's an error in this class implementation
|
||||
// (we default to non-null instances, and the setters should never allow null):
|
||||
Assert.stateNotNull(this.keyLocator, "Key locator should never be null.");
|
||||
// Invariants. If these are ever violated, it's an error in this class implementation:
|
||||
Assert.stateNotNull(keyLocator, "Key locator should never be null.");
|
||||
|
||||
final DefaultClaims expClaims = (DefaultClaims) this.expectedClaims.build();
|
||||
|
||||
return new ImmutableJwtParser(new DefaultJwtParser(
|
||||
return new DefaultJwtParser(
|
||||
provider,
|
||||
signingKeyResolver,
|
||||
enableUnsecuredJws,
|
||||
|
@ -328,6 +337,6 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
extraSigAlgs,
|
||||
extraKeyAlgs,
|
||||
extraEncAlgs
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Clock;
|
||||
import io.jsonwebtoken.CompressionCodecResolver;
|
||||
import io.jsonwebtoken.ExpiredJwtException;
|
||||
import io.jsonwebtoken.Header;
|
||||
import io.jsonwebtoken.Jwe;
|
||||
import io.jsonwebtoken.Jws;
|
||||
import io.jsonwebtoken.Jwt;
|
||||
import io.jsonwebtoken.JwtException;
|
||||
import io.jsonwebtoken.JwtHandler;
|
||||
import io.jsonwebtoken.JwtParser;
|
||||
import io.jsonwebtoken.MalformedJwtException;
|
||||
import io.jsonwebtoken.SigningKeyResolver;
|
||||
import io.jsonwebtoken.UnsupportedJwtException;
|
||||
import io.jsonwebtoken.io.Decoder;
|
||||
import io.jsonwebtoken.io.Deserializer;
|
||||
import io.jsonwebtoken.security.SignatureException;
|
||||
|
||||
import java.security.Key;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This JwtParser implementation exists as a stop gap until the mutable methods are removed from JwtParser.
|
||||
* TODO: remove this class BEFORE 1.0
|
||||
*
|
||||
* @since 0.11.0
|
||||
*/
|
||||
class ImmutableJwtParser implements JwtParser {
|
||||
|
||||
private final JwtParser jwtParser;
|
||||
|
||||
ImmutableJwtParser(JwtParser jwtParser) {
|
||||
this.jwtParser = jwtParser;
|
||||
}
|
||||
|
||||
private IllegalStateException doNotMutate() {
|
||||
return new IllegalStateException("Cannot mutate a JwtParser created from JwtParserBuilder.build(), " +
|
||||
"the mutable methods in JwtParser will be removed before version 1.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireId(String id) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireSubject(String subject) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireAudience(String audience) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireIssuer(String issuer) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireIssuedAt(Date issuedAt) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireExpiration(Date expiration) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser requireNotBefore(Date notBefore) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser require(String claimName, Object value) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setClock(Clock clock) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setAllowedClockSkewSeconds(long seconds) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKey(byte[] key) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKey(String base64EncodedSecretKey) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKey(Key key) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser base64UrlDecodeWith(Decoder<String, byte[]> base64UrlDecoder) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParser deserializeJsonWith(Deserializer<Map<String, ?>> deserializer) {
|
||||
throw doNotMutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSigned(String compact) {
|
||||
return this.jwtParser.isSigned(compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jwt<?, ?> parse(String jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
|
||||
return this.jwtParser.parse(jwt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T parse(String jwt, JwtHandler<T> handler) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
|
||||
return this.jwtParser.parse(jwt, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jwt<Header, byte[]> parseContentJwt(String jwt) throws UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
|
||||
return this.jwtParser.parseContentJwt(jwt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jwt<Header, Claims> parseClaimsJwt(String jwt) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
|
||||
return this.jwtParser.parseClaimsJwt(jwt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jws<byte[]> parseContentJws(String jws) throws UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
|
||||
return this.jwtParser.parseContentJws(jws);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jws<Claims> parseClaimsJws(String jws) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
|
||||
return this.jwtParser.parseClaimsJws(jws);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jwe<byte[]> parseContentJwe(String jwe) throws JwtException {
|
||||
return this.jwtParser.parseContentJwe(jwe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jwe<Claims> parseClaimsJwe(String jwe) throws JwtException {
|
||||
return this.jwtParser.parseClaimsJwe(jwe);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2019 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl.lang;
|
||||
|
||||
import io.jsonwebtoken.lang.Classes;
|
||||
import io.jsonwebtoken.lang.UnknownClassException;
|
||||
|
||||
/**
|
||||
* A backward compatibility {@link Services} utility to help migrate away from {@link Classes#newInstance(String)}.
|
||||
* TODO: remove before v1.0
|
||||
* @deprecated use {@link Services} directly
|
||||
*/
|
||||
@Deprecated
|
||||
public final class LegacyServices {
|
||||
|
||||
/**
|
||||
* Wraps {@code Services.loadFirst} and throws a {@link UnknownClassException} instead of a
|
||||
* {@link UnavailableImplementationException} to retain the previous behavior. This method should be used when
|
||||
* to retain the previous behavior of methods that throw an unchecked UnknownClassException.
|
||||
* @param <T> the type of object to return
|
||||
* @param spi the class for which to find the first instance
|
||||
* @return the first instance of type {@code T} found from a call to {@link Services#loadFirst(Class)}
|
||||
*/
|
||||
public static <T> T loadFirst(Class<T> spi) {
|
||||
try {
|
||||
return Services.loadFirst(spi);
|
||||
} catch (UnavailableImplementationException e) {
|
||||
throw new UnknownClassException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,18 +15,15 @@
|
|||
*/
|
||||
package io.jsonwebtoken.impl.security;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Header;
|
||||
import io.jsonwebtoken.JweHeader;
|
||||
import io.jsonwebtoken.JwsHeader;
|
||||
import io.jsonwebtoken.LocatorAdapter;
|
||||
import io.jsonwebtoken.SigningKeyResolver;
|
||||
import io.jsonwebtoken.impl.lang.Function;
|
||||
|
||||
import java.security.Key;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ConstantKeyLocator extends LocatorAdapter<Key> implements SigningKeyResolver, Function<Header, Key> {
|
||||
public class ConstantKeyLocator extends LocatorAdapter<Key> implements Function<Header, Key> {
|
||||
|
||||
private final Key jwsKey;
|
||||
private final Key jweKey;
|
||||
|
@ -36,16 +33,6 @@ public class ConstantKeyLocator extends LocatorAdapter<Key> implements SigningKe
|
|||
this.jweKey = jweKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key resolveSigningKey(JwsHeader header, Claims claims) {
|
||||
return locate(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key resolveSigningKey(JwsHeader header, byte[] content) {
|
||||
return locate(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Key locate(JwsHeader header) {
|
||||
return this.jwsKey;
|
||||
|
|
|
@ -37,13 +37,13 @@ class CustomObjectDeserializationTest {
|
|||
String jwtString = Jwts.builder().claim("cust", customBean).compact()
|
||||
|
||||
// no custom deserialization, object is a map
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(jwtString)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(jwtString)
|
||||
assertNotNull jwt
|
||||
assertEquals jwt.getPayload().get('cust'), [key1: 'value1', key2: 42]
|
||||
|
||||
// custom type for 'cust' claim
|
||||
Deserializer deserializer = new JacksonDeserializer([cust: CustomBean])
|
||||
jwt = Jwts.parserBuilder().enableUnsecuredJws().deserializeJsonWith(deserializer).build().parseClaimsJwt(jwtString)
|
||||
jwt = Jwts.parser().enableUnsecuredJws().deserializeJsonWith(deserializer).build().parseClaimsJwt(jwtString)
|
||||
assertNotNull jwt
|
||||
CustomBean result = jwt.getPayload().get("cust", CustomBean)
|
||||
assertEquals customBean, result
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,767 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.impl.DefaultHeader
|
||||
import io.jsonwebtoken.impl.DefaultJwsHeader
|
||||
import io.jsonwebtoken.impl.JwtTokenizer
|
||||
import io.jsonwebtoken.impl.compression.GzipCompressionAlgorithm
|
||||
import io.jsonwebtoken.impl.lang.Services
|
||||
import io.jsonwebtoken.impl.security.TestKeys
|
||||
import io.jsonwebtoken.io.Encoders
|
||||
import io.jsonwebtoken.io.Serializer
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import io.jsonwebtoken.security.Keys
|
||||
import io.jsonwebtoken.security.WeakKeyException
|
||||
import org.junit.Test
|
||||
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import java.nio.charset.Charset
|
||||
import java.security.KeyPair
|
||||
import java.security.PrivateKey
|
||||
import java.security.PublicKey
|
||||
|
||||
import static org.junit.Assert.*
|
||||
|
||||
@SuppressWarnings(['GrDeprecatedAPIUsage', 'GrUnnecessarySemicolon'])
|
||||
class DeprecatedJwtsTest {
|
||||
|
||||
private static Date now() {
|
||||
return dateWithOnlySecondPrecision(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private static int later() {
|
||||
def date = laterDate(10000)
|
||||
def seconds = date.getTime() / 1000
|
||||
return seconds as int
|
||||
}
|
||||
|
||||
private static Date laterDate(int seconds) {
|
||||
def millis = seconds * 1000L
|
||||
def time = System.currentTimeMillis() + millis
|
||||
return dateWithOnlySecondPrecision(time)
|
||||
}
|
||||
|
||||
private static Date dateWithOnlySecondPrecision(long millis) {
|
||||
long seconds = (millis / 1000) as long
|
||||
long secondOnlyPrecisionMillis = seconds * 1000
|
||||
return new Date(secondOnlyPrecisionMillis)
|
||||
}
|
||||
|
||||
protected static String base64Url(String s) {
|
||||
byte[] bytes = s.getBytes(Strings.UTF_8)
|
||||
return Encoders.BASE64URL.encode(bytes)
|
||||
}
|
||||
|
||||
protected static String toJson(o) {
|
||||
def serializer = Services.loadFirst(Serializer)
|
||||
byte[] bytes = serializer.serialize(o)
|
||||
return new String(bytes, Strings.UTF_8)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSubclass() {
|
||||
new Jwts()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHeaderWithNoArgs() {
|
||||
def header = Jwts.header().build()
|
||||
assertTrue header instanceof DefaultHeader
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHeaderWithMapArg() {
|
||||
def header = Jwts.header().set([alg: "HS256"]).build()
|
||||
assertTrue header instanceof DefaultJwsHeader
|
||||
assertEquals 'HS256', header.getAlgorithm()
|
||||
assertEquals 'HS256', header.alg
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClaims() {
|
||||
Claims claims = Jwts.claims().build()
|
||||
assertNotNull claims
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClaimsWithMapArg() {
|
||||
Claims claims = Jwts.claims([sub: 'Joe'])
|
||||
assertNotNull claims
|
||||
assertEquals claims.getSubject(), 'Joe'
|
||||
}
|
||||
|
||||
@Test
|
||||
void testContentJwtString() {
|
||||
|
||||
// Assert exact output per example at https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-6.1
|
||||
|
||||
// The base64url encoding of the example claims set in the spec shows that their original payload ends lines with
|
||||
// carriage return + newline, so we have to include them in the test payload to assert our encoded output
|
||||
// matches what is in the spec:
|
||||
|
||||
//noinspection HttpUrlsUsage
|
||||
def payload = '{"iss":"joe",\r\n' +
|
||||
' "exp":1300819380,\r\n' +
|
||||
' "http://example.com/is_root":true}'
|
||||
|
||||
String val = Jwts.builder().setPayload(payload).compact();
|
||||
|
||||
def specOutput = 'eyJhbGciOiJub25lIn0.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
|
||||
|
||||
assertEquals val, specOutput
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseContentToken() {
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
|
||||
def token = Jwts.parserBuilder().enableUnsecuredJws().build().parse(jwt);
|
||||
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.body == claims
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testParseNull() {
|
||||
Jwts.parser().parse(null)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testParseEmptyString() {
|
||||
Jwts.parser().parse('')
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testParseWhitespaceString() {
|
||||
Jwts.parser().parse(' ')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseWithNoPeriods() {
|
||||
try {
|
||||
Jwts.parser().parse('foo')
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = JwtTokenizer.DELIM_ERR_MSG_PREFIX + '0'
|
||||
assertEquals expected, e.message
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseWithOnePeriodOnly() {
|
||||
try {
|
||||
Jwts.parser().parse('.')
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = JwtTokenizer.DELIM_ERR_MSG_PREFIX + '1'
|
||||
assertEquals expected, e.message
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MalformedJwtException)
|
||||
void testParseWithTwoPeriodsOnly() {
|
||||
Jwts.parser().parse('..')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseWithHeaderOnly() {
|
||||
String unsecuredJwt = base64Url("{\"alg\":\"none\"}") + ".."
|
||||
Jwt jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parse(unsecuredJwt)
|
||||
assertEquals("none", jwt.getHeader().get("alg"))
|
||||
}
|
||||
|
||||
@Test(expected = MalformedJwtException)
|
||||
void testParseWithSignatureOnly() {
|
||||
Jwts.parser().parse('..bar')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceIssuer() {
|
||||
String compact = Jwts.builder().setIssuer("Me").compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertEquals claims.getIssuer(), "Me"
|
||||
|
||||
compact = Jwts.builder().setSubject("Joe")
|
||||
.setIssuer("Me") //set it
|
||||
.setIssuer(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getIssuer()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceSubject() {
|
||||
String compact = Jwts.builder().setSubject("Joe").compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertEquals claims.getSubject(), "Joe"
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
.setSubject("Joe") //set it
|
||||
.setSubject(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getSubject()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceAudience() {
|
||||
String compact = Jwts.builder().setAudience("You").compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertEquals claims.getAudience(), "You"
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
.setAudience("You") //set it
|
||||
.setAudience(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getAudience()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceExpiration() {
|
||||
Date then = laterDate(10000)
|
||||
String compact = Jwts.builder().setExpiration(then).compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
def claimedDate = claims.getExpiration()
|
||||
assertEquals claimedDate, then
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
.setExpiration(then) //set it
|
||||
.setExpiration(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getExpiration()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceNotBefore() {
|
||||
Date now = now() //jwt exp only supports *seconds* since epoch:
|
||||
String compact = Jwts.builder().setNotBefore(now).compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
def claimedDate = claims.getNotBefore()
|
||||
assertEquals claimedDate, now
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
.setNotBefore(now) //set it
|
||||
.setNotBefore(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getNotBefore()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceIssuedAt() {
|
||||
Date now = now() //jwt exp only supports *seconds* since epoch:
|
||||
String compact = Jwts.builder().setIssuedAt(now).compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
def claimedDate = claims.getIssuedAt()
|
||||
assertEquals claimedDate, now
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
.setIssuedAt(now) //set it
|
||||
.setIssuedAt(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getIssuedAt()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceId() {
|
||||
String id = UUID.randomUUID().toString();
|
||||
String compact = Jwts.builder().setId(id).compact();
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertEquals claims.getId(), id
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
.setId(id) //set it
|
||||
.setId(null) //null should remove it
|
||||
.compact();
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).body as Claims
|
||||
assertNull claims.getId()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUncompressedJwt() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(alg, key)
|
||||
.claim("state", "hello this is an amazing jwt").compact()
|
||||
|
||||
def jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.body
|
||||
|
||||
assertNull jws.header.getCompressionAlgorithm()
|
||||
|
||||
assertEquals id, claims.getId()
|
||||
assertEquals "an audience", claims.getAudience()
|
||||
assertEquals "hello this is an amazing jwt", claims.state
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompressedJwtWithDeflate() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(alg, key)
|
||||
.claim("state", "hello this is an amazing jwt").compressWith(Jwts.ZIP.DEF).compact()
|
||||
|
||||
def jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.body
|
||||
|
||||
assertEquals "DEF", jws.header.getCompressionAlgorithm()
|
||||
|
||||
assertEquals id, claims.getId()
|
||||
assertEquals "an audience", claims.getAudience()
|
||||
assertEquals "hello this is an amazing jwt", claims.state
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompressedJwtWithGZIP() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(alg, key)
|
||||
.claim("state", "hello this is an amazing jwt").compressWith(Jwts.ZIP.GZIP).compact()
|
||||
|
||||
def jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.body
|
||||
|
||||
assertEquals "GZIP", jws.header.getCompressionAlgorithm()
|
||||
|
||||
assertEquals id, claims.getId()
|
||||
assertEquals "an audience", claims.getAudience()
|
||||
assertEquals "hello this is an amazing jwt", claims.state
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompressedWithCustomResolver() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(alg, key)
|
||||
.claim("state", "hello this is an amazing jwt").compressWith(new GzipCompressionAlgorithm() {
|
||||
@Override
|
||||
String getId() {
|
||||
return "CUSTOM"
|
||||
}
|
||||
}).compact()
|
||||
|
||||
def jws = Jwts.parser().setSigningKey(key).setCompressionCodecResolver(new CompressionCodecResolver() {
|
||||
@Override
|
||||
CompressionCodec resolveCompressionCodec(Header header) throws CompressionException {
|
||||
String algorithm = header.getCompressionAlgorithm()
|
||||
//noinspection ChangeToOperator
|
||||
if ("CUSTOM".equals(algorithm)) {
|
||||
return Jwts.ZIP.GZIP as CompressionCodec
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}).parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.body
|
||||
|
||||
assertEquals "CUSTOM", jws.header.getCompressionAlgorithm()
|
||||
|
||||
assertEquals id, claims.getId()
|
||||
assertEquals "an audience", claims.getAudience()
|
||||
assertEquals "hello this is an amazing jwt", claims.state
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedJwtException.class)
|
||||
void testCompressedJwtWithUnrecognizedHeader() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(alg, key)
|
||||
.claim("state", "hello this is an amazing jwt").compressWith(new GzipCompressionAlgorithm() {
|
||||
@Override
|
||||
String getId() {
|
||||
return "CUSTOM"
|
||||
}
|
||||
}).compact()
|
||||
|
||||
Jwts.parser().setSigningKey(key).parseClaimsJws(compact)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompressStringPayloadWithDeflate() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String payload = "this is my test for a payload"
|
||||
|
||||
String compact = Jwts.builder().setPayload(payload).signWith(alg, key)
|
||||
.compressWith(Jwts.ZIP.DEF).compact()
|
||||
|
||||
def jws = Jwts.parser().setSigningKey(key).parseContentJws(compact)
|
||||
|
||||
byte[] parsed = jws.body
|
||||
|
||||
assertEquals "DEF", jws.header.getCompressionAlgorithm()
|
||||
|
||||
assertEquals "this is my test for a payload", Strings.utf8(parsed)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHS256() {
|
||||
testHmac(SignatureAlgorithm.HS256)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHS384() {
|
||||
testHmac(SignatureAlgorithm.HS384)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHS512() {
|
||||
testHmac(SignatureAlgorithm.HS512)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRS256() {
|
||||
testRsa(SignatureAlgorithm.RS256)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRS384() {
|
||||
testRsa(SignatureAlgorithm.RS384)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRS512() {
|
||||
testRsa(SignatureAlgorithm.RS512)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPS256() {
|
||||
testRsa(SignatureAlgorithm.PS256)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPS384() {
|
||||
testRsa(SignatureAlgorithm.PS384)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPS512() {
|
||||
testRsa(SignatureAlgorithm.PS512)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRSA256WithPrivateKeyValidation() {
|
||||
testRsa(SignatureAlgorithm.RS256, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRSA384WithPrivateKeyValidation() {
|
||||
testRsa(SignatureAlgorithm.RS384, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRSA512WithPrivateKeyValidation() {
|
||||
testRsa(SignatureAlgorithm.RS512, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testES256() {
|
||||
testEC(SignatureAlgorithm.ES256)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testES384() {
|
||||
testEC(SignatureAlgorithm.ES384)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testES512() {
|
||||
testEC(SignatureAlgorithm.ES512)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testES256WithPrivateKeyValidation() {
|
||||
def alg = SignatureAlgorithm.ES256;
|
||||
try {
|
||||
testEC(alg, true)
|
||||
fail("EC private keys cannot be used to validate EC signatures.")
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String msg = "${alg.name()} verification keys must be PublicKeys (implement java.security.PublicKey). " +
|
||||
"Provided key type: sun.security.ec.ECPrivateKeyImpl."
|
||||
assertEquals msg, e.cause.message
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseClaimsJwsWithWeakHmacKey() {
|
||||
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS384
|
||||
def key = Keys.secretKeyFor(alg)
|
||||
def weakKey = Keys.secretKeyFor(SignatureAlgorithm.HS256)
|
||||
|
||||
String jws = Jwts.builder().setSubject("Foo").signWith(key, alg).compact()
|
||||
|
||||
//noinspection GroovyUnusedCatchParameter
|
||||
try {
|
||||
Jwts.parser().setSigningKey(weakKey).parseClaimsJws(jws)
|
||||
fail('parseClaimsJws must fail for weak keys')
|
||||
} catch (WeakKeyException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
//Asserts correct/expected behavior discussed in https://github.com/jwtk/jjwt/issues/20
|
||||
@Test
|
||||
void testParseClaimsJwsWithUnsignedJwt() {
|
||||
|
||||
//create random signing key for testing:
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
String notSigned = Jwts.builder().setSubject("Foo").compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(notSigned)
|
||||
fail('parseClaimsJws must fail for unsigned JWTs')
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertEquals 'Unprotected Claims JWTs are not supported.', expected.message
|
||||
}
|
||||
}
|
||||
|
||||
//Asserts correct/expected behavior discussed in https://github.com/jwtk/jjwt/issues/20
|
||||
@Test
|
||||
void testForgedTokenWithSwappedHeaderUsingNoneAlgorithm() {
|
||||
|
||||
//create random signing key for testing:
|
||||
SignatureAlgorithm alg = SignatureAlgorithm.HS256
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
//this is a 'real', valid JWT:
|
||||
String compact = Jwts.builder().setSubject("Joe").signWith(alg, key).compact()
|
||||
|
||||
//Now strip off the signature so we can add it back in later on a forged token:
|
||||
int i = compact.lastIndexOf('.')
|
||||
String signature = compact.substring(i + 1)
|
||||
|
||||
//now let's create a fake header and payload with whatever we want (without signing):
|
||||
String forged = Jwts.builder().setSubject("Not Joe").compact()
|
||||
|
||||
//assert that our forged header has a 'NONE' algorithm:
|
||||
assertEquals 'none', Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(forged).getHeader().get('alg')
|
||||
|
||||
//now let's forge it by appending the signature the server expects:
|
||||
forged += signature
|
||||
|
||||
//now assert that, when the server tries to parse the forged token, parsing fails:
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parse(forged)
|
||||
fail("Parsing must fail for a forged token.")
|
||||
} catch (MalformedJwtException expected) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', expected.message
|
||||
}
|
||||
}
|
||||
|
||||
//Asserts correct/expected behavior discussed in https://github.com/jwtk/jjwt/issues/20 and https://github.com/jwtk/jjwt/issues/25
|
||||
@Test
|
||||
void testParseForgedRsaPublicKeyAsHmacTokenVerifiedWithTheRsaPrivateKey() {
|
||||
|
||||
//Create a legitimate RSA public and private key pair:
|
||||
KeyPair kp = TestKeys.RS256.pair
|
||||
PublicKey publicKey = kp.getPublic()
|
||||
PrivateKey privateKey = kp.getPrivate()
|
||||
|
||||
String header = base64Url(toJson(['alg': 'HS256']))
|
||||
String body = base64Url(toJson('foo'))
|
||||
String compact = header + '.' + body + '.'
|
||||
|
||||
// Now for the forgery: simulate an attacker using the RSA public key to sign a token, but
|
||||
// using it as an HMAC signing key instead of RSA:
|
||||
Mac mac = Mac.getInstance('HmacSHA256');
|
||||
mac.init(new SecretKeySpec(publicKey.getEncoded(), 'HmacSHA256'));
|
||||
byte[] signatureBytes = mac.doFinal(compact.getBytes(Charset.forName('US-ASCII')))
|
||||
String encodedSignature = Encoders.BASE64URL.encode(signatureBytes)
|
||||
|
||||
//Finally, the forged token is the header + body + forged signature:
|
||||
String forged = compact + encodedSignature;
|
||||
|
||||
// Assert that the server (that should always use the private key) does not recognized the forged token:
|
||||
try {
|
||||
Jwts.parser().setSigningKey(privateKey).parse(forged);
|
||||
fail("Forged token must not be successfully parsed.")
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertTrue expected.getMessage().startsWith('The parsed JWT indicates it was signed with the')
|
||||
}
|
||||
}
|
||||
|
||||
//Asserts correct behavior for https://github.com/jwtk/jjwt/issues/25
|
||||
@Test
|
||||
void testParseForgedRsaPublicKeyAsHmacTokenVerifiedWithTheRsaPublicKey() {
|
||||
|
||||
//Create a legitimate RSA public and private key pair:
|
||||
KeyPair kp = TestKeys.RS256.pair
|
||||
PublicKey publicKey = kp.getPublic();
|
||||
//PrivateKey privateKey = kp.getPrivate();
|
||||
|
||||
String header = base64Url(toJson(['alg': 'HS256']))
|
||||
String body = base64Url(toJson('foo'))
|
||||
String compact = header + '.' + body + '.'
|
||||
|
||||
// Now for the forgery: simulate an attacker using the RSA public key to sign a token, but
|
||||
// using it as an HMAC signing key instead of RSA:
|
||||
Mac mac = Mac.getInstance('HmacSHA256');
|
||||
mac.init(new SecretKeySpec(publicKey.getEncoded(), 'HmacSHA256'));
|
||||
byte[] signatureBytes = mac.doFinal(compact.getBytes(Charset.forName('US-ASCII')))
|
||||
String encodedSignature = Encoders.BASE64URL.encode(signatureBytes);
|
||||
|
||||
//Finally, the forged token is the header + body + forged signature:
|
||||
String forged = compact + encodedSignature;
|
||||
|
||||
// Assert that the parser does not recognized the forged token:
|
||||
try {
|
||||
Jwts.parser().setSigningKey(publicKey).parse(forged);
|
||||
fail("Forged token must not be successfully parsed.")
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertTrue expected.getMessage().startsWith('The parsed JWT indicates it was signed with the')
|
||||
}
|
||||
}
|
||||
|
||||
//Asserts correct behavior for https://github.com/jwtk/jjwt/issues/25
|
||||
@Test
|
||||
void testParseForgedEllipticCurvePublicKeyAsHmacToken() {
|
||||
|
||||
//Create a legitimate RSA public and private key pair:
|
||||
KeyPair kp = TestKeys.ES256.pair
|
||||
PublicKey publicKey = kp.getPublic();
|
||||
//PrivateKey privateKey = kp.getPrivate();
|
||||
|
||||
String header = base64Url(toJson(['alg': 'HS256']))
|
||||
String body = base64Url(toJson('foo'))
|
||||
String compact = header + '.' + body + '.'
|
||||
|
||||
// Now for the forgery: simulate an attacker using the Elliptic Curve public key to sign a token, but
|
||||
// using it as an HMAC signing key instead of Elliptic Curve:
|
||||
Mac mac = Mac.getInstance('HmacSHA256');
|
||||
mac.init(new SecretKeySpec(publicKey.getEncoded(), 'HmacSHA256'));
|
||||
byte[] signatureBytes = mac.doFinal(compact.getBytes(Charset.forName('US-ASCII')))
|
||||
String encodedSignature = Encoders.BASE64URL.encode(signatureBytes);
|
||||
|
||||
//Finally, the forged token is the header + body + forged signature:
|
||||
String forged = compact + encodedSignature;
|
||||
|
||||
// Assert that the parser does not recognized the forged token:
|
||||
try {
|
||||
Jwts.parser().setSigningKey(publicKey).parse(forged)
|
||||
fail("Forged token must not be successfully parsed.")
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertTrue expected.getMessage().startsWith('The parsed JWT indicates it was signed with the')
|
||||
}
|
||||
}
|
||||
|
||||
static void testRsa(SignatureAlgorithm alg, boolean verifyWithPrivateKey = false) {
|
||||
|
||||
KeyPair kp = Keys.keyPairFor(alg)
|
||||
PublicKey publicKey = kp.getPublic()
|
||||
PrivateKey privateKey = kp.getPrivate()
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(privateKey, alg).compact()
|
||||
|
||||
def key = publicKey
|
||||
if (verifyWithPrivateKey) {
|
||||
key = privateKey
|
||||
}
|
||||
|
||||
def token = Jwts.parser().setSigningKey(key).parse(jwt)
|
||||
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert [alg: alg.name()] == token.header
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.body == claims
|
||||
}
|
||||
|
||||
static void testHmac(SignatureAlgorithm alg) {
|
||||
|
||||
//create random signing key for testing:
|
||||
byte[] key = Keys.secretKeyFor(alg).encoded
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(alg, key).compact()
|
||||
|
||||
def token = Jwts.parser().setSigningKey(key).parse(jwt)
|
||||
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.header == [alg: alg.name()]
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.body == claims
|
||||
}
|
||||
|
||||
static void testEC(SignatureAlgorithm alg, boolean verifyWithPrivateKey = false) {
|
||||
|
||||
KeyPair pair = Keys.keyPairFor(alg)
|
||||
PublicKey publicKey = pair.getPublic()
|
||||
PrivateKey privateKey = pair.getPrivate()
|
||||
|
||||
def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(privateKey, alg).compact()
|
||||
|
||||
def key = publicKey
|
||||
if (verifyWithPrivateKey) {
|
||||
key = privateKey
|
||||
}
|
||||
|
||||
def token = Jwts.parser().setSigningKey(key).parse(jwt)
|
||||
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.header == [alg: alg.name()]
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.body == claims
|
||||
}
|
||||
}
|
||||
|
|
@ -53,12 +53,12 @@ class JwtParserTest {
|
|||
|
||||
@Test
|
||||
void testIsSignedWithNullArgument() {
|
||||
assertFalse Jwts.parserBuilder().build().isSigned(null)
|
||||
assertFalse Jwts.parser().build().isSigned(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsSignedWithJunkArgument() {
|
||||
assertFalse Jwts.parserBuilder().build().isSigned('hello')
|
||||
assertFalse Jwts.parser().build().isSigned('hello')
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -69,7 +69,7 @@ class JwtParserTest {
|
|||
String bad = base64Url('{"alg":"none"}') + '.' + base64Url(junkPayload) + '.'
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parse(bad)
|
||||
Jwts.parser().enableUnsecuredJws().build().parse(bad)
|
||||
fail()
|
||||
} catch (MalformedJwtException expected) {
|
||||
assertEquals 'Unable to read claims JSON: ' + junkPayload, expected.getMessage()
|
||||
|
@ -90,7 +90,7 @@ class JwtParserTest {
|
|||
String bad = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(badSig)
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(randomKey()).build().parse(bad)
|
||||
Jwts.parser().setSigningKey(randomKey()).build().parse(bad)
|
||||
fail()
|
||||
} catch (SignatureException se) {
|
||||
assertEquals se.getMessage(), "Unsupported signature algorithm '$badAlgorithmName'".toString()
|
||||
|
@ -109,7 +109,7 @@ class JwtParserTest {
|
|||
String bad = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(badSig)
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(randomKey()).build().parse(bad)
|
||||
Jwts.parser().setSigningKey(randomKey()).build().parse(bad)
|
||||
fail()
|
||||
} catch (SignatureException se) {
|
||||
assertEquals se.getMessage(), 'JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.'
|
||||
|
@ -129,7 +129,7 @@ class JwtParserTest {
|
|||
String bad = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(badSig)
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(randomKey()).build().parse(bad)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(randomKey()).build().parse(bad)
|
||||
fail()
|
||||
} catch (MalformedJwtException se) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', se.getMessage()
|
||||
|
@ -147,7 +147,7 @@ class JwtParserTest {
|
|||
def payload = '{"subject":"Joe"}'
|
||||
String unsecured = base64Url(header) + '.' + base64Url(payload) + '.'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse(unsecured)
|
||||
Jwts.parser().build().parse(unsecured)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
String msg = DefaultJwtParser.UNSECURED_DISABLED_MSG_PREFIX + '{alg=none}'
|
||||
|
@ -167,9 +167,9 @@ class JwtParserTest {
|
|||
//noinspection GrDeprecatedAPIUsage
|
||||
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, base64Encodedkey).compact()
|
||||
|
||||
assertTrue Jwts.parserBuilder().build().isSigned(compact)
|
||||
assertTrue Jwts.parser().build().isSigned(compact)
|
||||
|
||||
def jwt = Jwts.parserBuilder().setSigningKey(base64Encodedkey).build().parse(compact)
|
||||
def jwt = Jwts.parser().setSigningKey(base64Encodedkey).build().parse(compact)
|
||||
|
||||
assertEquals payload, new String(jwt.payload as byte[], StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -182,9 +182,9 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setPayload(payload).signWith(key).compact()
|
||||
|
||||
assertTrue Jwts.parserBuilder().build().isSigned(compact)
|
||||
assertTrue Jwts.parser().build().isSigned(compact)
|
||||
|
||||
def jwt = Jwts.parserBuilder().setSigningKey(key).build().parse(compact)
|
||||
def jwt = Jwts.parser().setSigningKey(key).build().parse(compact)
|
||||
|
||||
assertEquals payload, new String(jwt.payload as byte[], StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -193,16 +193,16 @@ class JwtParserTest {
|
|||
void testParseNullPayload() {
|
||||
SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256)
|
||||
String compact = Jwts.builder().signWith(key).compact()
|
||||
assertTrue Jwts.parserBuilder().build().isSigned(compact)
|
||||
assertTrue Jwts.parser().build().isSigned(compact)
|
||||
|
||||
def jwt = Jwts.parserBuilder().setSigningKey(key).build().parse(compact)
|
||||
def jwt = Jwts.parser().setSigningKey(key).build().parse(compact)
|
||||
assertEquals '', new String(jwt.payload as byte[], StandardCharsets.UTF_8)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseNullPayloadWithoutKey() {
|
||||
String compact = Jwts.builder().compact()
|
||||
def jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact)
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parse(compact)
|
||||
assertEquals 'none', jwt.header.alg
|
||||
assertEquals '', new String(jwt.payload as byte[], StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setClock(fixedClock).build().parse(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setClock(fixedClock).build().parse(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
// https://github.com/jwtk/jjwt/issues/107 (the Z designator at the end of the timestamp):
|
||||
|
@ -237,7 +237,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setNotBefore(nbf).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact)
|
||||
Jwts.parser().enableUnsecuredJws().build().parse(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -254,7 +254,7 @@ class JwtParserTest {
|
|||
String subject = 'Joe'
|
||||
String compact = Jwts.builder().setSubject(subject).setExpiration(exp).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().enableUnsecuredJws().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -280,7 +280,7 @@ class JwtParserTest {
|
|||
String subject = 'Joe'
|
||||
String compact = Jwts.builder().setSubject(subject).setNotBefore(exp).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().enableUnsecuredJws().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setNotBefore(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -310,7 +310,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
def jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
|
||||
assertEquals payload, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals e.getMessage(), 'Unprotected Claims JWTs are not supported.'
|
||||
|
@ -336,7 +336,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, randomKey()).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseContentJwt(compact)
|
||||
Jwts.parser().build().parseContentJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Cannot verify JWS signature: unable to locate signature verification key for JWS with header: {alg=HS256}', e.getMessage()
|
||||
|
@ -350,7 +350,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
|
||||
|
@ -368,7 +368,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setSubject(subject).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
|
||||
|
@ -396,7 +396,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, randomKey()).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Cannot verify JWS signature: unable to locate signature verification key for JWS with header: {alg=HS256}', e.getMessage()
|
||||
|
@ -410,7 +410,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJwt(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
|
||||
|
@ -427,7 +427,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -442,7 +442,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setNotBefore(nbf).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -462,7 +462,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
def jwt = Jwts.parserBuilder().
|
||||
def jwt = Jwts.parser().
|
||||
setSigningKey(key).
|
||||
build().
|
||||
parseContentJws(compact)
|
||||
|
@ -480,7 +480,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
|
||||
|
@ -497,7 +497,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected Claims JWTs are not supported.', e.getMessage()
|
||||
|
@ -514,7 +514,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
|
||||
|
@ -534,7 +534,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setSubject(sub).signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), sub
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(sub).signWith(SignatureAlgorithm.HS256, key).setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJwt(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -574,7 +574,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(sub).setNotBefore(nbf).signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -593,7 +593,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
|
||||
|
@ -610,7 +610,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
fail()
|
||||
|
@ -629,7 +629,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Signed Claims JWTs are not supported.', e.getMessage()
|
||||
|
@ -656,7 +656,7 @@ class JwtParserTest {
|
|||
}
|
||||
}
|
||||
|
||||
Jws jws = Jwts.parserBuilder().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
|
||||
Jws jws = Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
|
||||
|
||||
assertEquals jws.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -678,7 +678,7 @@ class JwtParserTest {
|
|||
}
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(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()
|
||||
|
@ -695,7 +695,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKeyResolver(null).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKeyResolver(null).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (IllegalArgumentException iae) {
|
||||
assertEquals 'SigningKeyResolver cannot be null.', iae.getMessage()
|
||||
|
@ -714,7 +714,7 @@ class JwtParserTest {
|
|||
def signingKeyResolver = new SigningKeyResolverAdapter()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException ex) {
|
||||
assertEquals 'The specified SigningKeyResolver implementation does not support ' +
|
||||
|
@ -742,7 +742,7 @@ class JwtParserTest {
|
|||
claim("long_big", bigLong).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jwt.getPayload()
|
||||
|
||||
|
@ -773,7 +773,7 @@ class JwtParserTest {
|
|||
}
|
||||
}
|
||||
|
||||
def jws = Jwts.parserBuilder().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
|
||||
def jws = Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
|
||||
|
||||
assertEquals inputPayload, new String(jws.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -795,7 +795,7 @@ class JwtParserTest {
|
|||
}
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
|
||||
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(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()
|
||||
|
@ -814,7 +814,7 @@ class JwtParserTest {
|
|||
def signingKeyResolver = new SigningKeyResolverAdapter()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
|
||||
Jwts.parser().setSigningKeyResolver(signingKeyResolver).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException ex) {
|
||||
assertEquals ex.getMessage(), 'The specified SigningKeyResolver implementation does not support content ' +
|
||||
|
@ -834,7 +834,7 @@ class JwtParserTest {
|
|||
|
||||
try {
|
||||
// expecting null claim name, but with value
|
||||
Jwts.parserBuilder().setSigningKey(key).require(null, expectedClaimValue).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKey(key).require(null, expectedClaimValue).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals(
|
||||
|
@ -857,7 +857,7 @@ class JwtParserTest {
|
|||
|
||||
try {
|
||||
// expecting null claim name, but with value
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
require("", expectedClaimValue).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -881,7 +881,7 @@ class JwtParserTest {
|
|||
|
||||
try {
|
||||
// expecting claim name, but with null value
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
require(expectedClaimName, null).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -905,7 +905,7 @@ class JwtParserTest {
|
|||
claim(expectedClaimName, expectedClaimValue).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
require(expectedClaimName, expectedClaimValue).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -927,7 +927,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
require(goodClaimName, goodClaimValue).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -952,7 +952,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
require(claimName, claimValue).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -976,7 +976,7 @@ class JwtParserTest {
|
|||
setIssuedAt(issuedAt).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireIssuedAt(issuedAt).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -995,7 +995,7 @@ class JwtParserTest {
|
|||
setIssuedAt(badIssuedAt).
|
||||
compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireIssuedAt(goodIssuedAt).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1011,7 +1011,7 @@ class JwtParserTest {
|
|||
setSubject("Dummy").
|
||||
compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireIssuedAt(issuedAt).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1027,7 +1027,7 @@ class JwtParserTest {
|
|||
setIssuer(issuer).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireIssuer(issuer).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1047,7 +1047,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireIssuer(goodIssuer).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1071,7 +1071,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireIssuer(issuer).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1094,7 +1094,7 @@ class JwtParserTest {
|
|||
setAudience(audience).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireAudience(audience).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1114,7 +1114,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireAudience(goodAudience).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1138,7 +1138,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireAudience(audience).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1161,7 +1161,7 @@ class JwtParserTest {
|
|||
setSubject(subject).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireSubject(subject).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1181,7 +1181,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireSubject(goodSubject).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1205,7 +1205,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireSubject(subject).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1228,7 +1228,7 @@ class JwtParserTest {
|
|||
setId(id).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireId(id).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1248,7 +1248,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireId(goodId).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1272,7 +1272,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireId(id).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1296,7 +1296,7 @@ class JwtParserTest {
|
|||
setExpiration(expiration).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireExpiration(expiration).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1315,7 +1315,7 @@ class JwtParserTest {
|
|||
setExpiration(badExpiration).
|
||||
compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireExpiration(goodExpiration).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1331,7 +1331,7 @@ class JwtParserTest {
|
|||
setSubject("Dummy").
|
||||
compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireExpiration(expiration).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1348,7 +1348,7 @@ class JwtParserTest {
|
|||
setNotBefore(notBefore).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
requireNotBefore(notBefore).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1367,7 +1367,7 @@ class JwtParserTest {
|
|||
setNotBefore(badNotBefore).
|
||||
compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireNotBefore(goodNotBefore).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1383,7 +1383,7 @@ class JwtParserTest {
|
|||
setSubject("Dummy").
|
||||
compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
requireNotBefore(notBefore).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1400,7 +1400,7 @@ class JwtParserTest {
|
|||
claim("aDate", aDate).
|
||||
compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().setSigningKey(key).
|
||||
require("aDate", aDate).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1422,7 +1422,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
require("aDate", goodDate).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1447,7 +1447,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
require("aDate", goodDate).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1471,7 +1471,7 @@ class JwtParserTest {
|
|||
compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).
|
||||
Jwts.parser().setSigningKey(key).
|
||||
require("aDate", aDate).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
|
@ -1492,12 +1492,12 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
|
||||
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setClock(new FixedClock(beforeExpiry)).build().parse(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setClock(new FixedClock(beforeExpiry)).build().parse(compact)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseClockManipulationWithNullClock() {
|
||||
JwtParserBuilder parser = Jwts.parserBuilder();
|
||||
JwtParserBuilder parser = Jwts.parser();
|
||||
try {
|
||||
parser.setClock(null)
|
||||
fail()
|
||||
|
@ -1512,7 +1512,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setClock(new DefaultClock()).build().parse(compact)
|
||||
Jwts.parser().enableUnsecuredJws().setClock(new DefaultClock()).build().parse(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -1533,7 +1533,7 @@ class JwtParserTest {
|
|||
String bad = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(badSig) + '.' + base64Url(bogus)
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(randomKey()).build().parse(bad)
|
||||
Jwts.parser().setSigningKey(randomKey()).build().parse(bad)
|
||||
fail()
|
||||
} catch (MalformedJwtException se) {
|
||||
String expected = JwtTokenizer.DELIM_ERR_MSG_PREFIX + '3'
|
||||
|
@ -1549,7 +1549,7 @@ class JwtParserTest {
|
|||
String jwtStr = '.' + base64Url(payload) + '.'
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse(jwtStr)
|
||||
Jwts.parser().build().parse(jwtStr)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
assertEquals 'Compact JWT strings MUST always have a Base64Url protected header per https://tools.ietf.org/html/rfc7519#section-7.2 (steps 2-4).', e.getMessage()
|
||||
|
@ -1566,7 +1566,7 @@ class JwtParserTest {
|
|||
String jwtStr = '.' + base64Url(payload) + '.' + base64Url(sig)
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse(jwtStr)
|
||||
Jwts.parser().build().parse(jwtStr)
|
||||
fail()
|
||||
} catch (MalformedJwtException se) {
|
||||
assertEquals 'Compact JWT strings MUST always have a Base64Url protected header per https://tools.ietf.org/html/rfc7519#section-7.2 (steps 2-4).', se.message
|
||||
|
@ -1585,7 +1585,7 @@ class JwtParserTest {
|
|||
String jwtStr = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(sig)
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().build().parse(jwtStr)
|
||||
Jwts.parser().enableUnsecuredJws().build().parse(jwtStr)
|
||||
fail()
|
||||
} catch (MalformedJwtException se) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', se.message
|
||||
|
|
|
@ -118,7 +118,7 @@ class JwtsTest {
|
|||
def encodedClaims = base64Url(claimsString)
|
||||
def compact = encodedHeader + '.' + encodedClaims + '.AAD='
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJws(compact)
|
||||
Jwts.parser().build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = 'Invalid protected header: Invalid JWS header \'jku\' (JWK Set URL) value: 42. ' +
|
||||
|
@ -141,7 +141,7 @@ class JwtsTest {
|
|||
def sig = Encoders.BASE64URL.encode(result)
|
||||
def compact = "$h.$c.$sig" as String
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = 'Invalid claims: Invalid JWT Claim \'exp\' (Expiration Time) value: -42-. ' +
|
||||
|
@ -166,7 +166,7 @@ class JwtsTest {
|
|||
String s = 'Hello JJWT'
|
||||
String cty = 'text/plain'
|
||||
String compact = Jwts.builder().setContent(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
assertEquals cty, jwt.header.getContentType()
|
||||
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ class JwtsTest {
|
|||
String subtype = 'foo'
|
||||
String cty = "application/$subtype"
|
||||
String compact = Jwts.builder().setContent(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
assertEquals subtype, jwt.header.getContentType() // assert that the compact form was used
|
||||
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ class JwtsTest {
|
|||
String subtype = 'foo'
|
||||
String cty = "application/$subtype;part=1/2"
|
||||
String compact = Jwts.builder().setContent(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
assertEquals cty, jwt.header.getContentType() // two slashes, can't compact
|
||||
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ class JwtsTest {
|
|||
|
||||
String jwt = Jwts.builder().setClaims(claims).compact()
|
||||
|
||||
def token = Jwts.parserBuilder().enableUnsecuredJws().build().parse(jwt)
|
||||
def token = Jwts.parser().enableUnsecuredJws().build().parse(jwt)
|
||||
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.payload == claims
|
||||
|
@ -208,17 +208,17 @@ class JwtsTest {
|
|||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testParseNull() {
|
||||
Jwts.parserBuilder().build().parse(null)
|
||||
Jwts.parser().build().parse(null)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testParseEmptyString() {
|
||||
Jwts.parserBuilder().build().parse('')
|
||||
Jwts.parser().build().parse('')
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testParseWhitespaceString() {
|
||||
Jwts.parserBuilder().build().parse(' ')
|
||||
Jwts.parser().build().parse(' ')
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -230,7 +230,7 @@ class JwtsTest {
|
|||
String claims = Encoders.BASE64URL.encode(claimsJson.getBytes(StandardCharsets.UTF_8))
|
||||
|
||||
String compact = header + '.' + claims + '.'
|
||||
def jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
assertEquals 'none', jwt.header.getAlgorithm()
|
||||
assertEquals 'joe', jwt.payload.getSubject()
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParseWithNoPeriods() {
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse('foo')
|
||||
Jwts.parser().build().parse('foo')
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
//noinspection GroovyAccessibility
|
||||
|
@ -250,7 +250,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParseWithOnePeriodOnly() {
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse('.')
|
||||
Jwts.parser().build().parse('.')
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
//noinspection GroovyAccessibility
|
||||
|
@ -262,7 +262,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParseWithTwoPeriodsOnly() {
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse('..')
|
||||
Jwts.parser().build().parse('..')
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String msg = 'Compact JWT strings MUST always have a Base64Url protected header per ' +
|
||||
|
@ -274,14 +274,14 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParseWithHeaderOnly() {
|
||||
String unsecuredJwt = base64Url("{\"alg\":\"none\"}") + ".."
|
||||
Jwt jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parse(unsecuredJwt)
|
||||
Jwt jwt = Jwts.parser().enableUnsecuredJws().build().parse(unsecuredJwt)
|
||||
assertEquals "none", jwt.getHeader().get("alg")
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseWithSignatureOnly() {
|
||||
try {
|
||||
Jwts.parserBuilder().build().parse('..bar')
|
||||
Jwts.parser().build().parse('..bar')
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
assertEquals 'Compact JWT strings MUST always have a Base64Url protected header per https://tools.ietf.org/html/rfc7519#section-7.2 (steps 2-4).', e.message
|
||||
|
@ -295,7 +295,7 @@ class JwtsTest {
|
|||
int i = compact.lastIndexOf('.')
|
||||
String missingSig = compact.substring(0, i + 1)
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(missingSig)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(missingSig)
|
||||
fail()
|
||||
} catch (MalformedJwtException expected) {
|
||||
String s = String.format(DefaultJwtParser.MISSING_JWS_DIGEST_MSG_FMT, 'HS256')
|
||||
|
@ -315,7 +315,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testConvenienceIssuer() {
|
||||
String compact = Jwts.builder().setIssuer("Me").compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertEquals 'Me', claims.getIssuer()
|
||||
|
||||
compact = Jwts.builder().setSubject("Joe")
|
||||
|
@ -323,14 +323,14 @@ class JwtsTest {
|
|||
.setIssuer(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getIssuer()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceSubject() {
|
||||
String compact = Jwts.builder().setSubject("Joe").compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertEquals 'Joe', claims.getSubject()
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
|
@ -338,14 +338,14 @@ class JwtsTest {
|
|||
.setSubject(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getSubject()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceAudience() {
|
||||
String compact = Jwts.builder().setAudience("You").compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertEquals 'You', claims.getAudience()
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
|
@ -353,7 +353,7 @@ class JwtsTest {
|
|||
.setAudience(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getAudience()
|
||||
}
|
||||
|
||||
|
@ -361,7 +361,7 @@ class JwtsTest {
|
|||
void testConvenienceExpiration() {
|
||||
Date then = laterDate(10000)
|
||||
String compact = Jwts.builder().setExpiration(then).compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
def claimedDate = claims.getExpiration()
|
||||
assertEquals then, claimedDate
|
||||
|
||||
|
@ -370,7 +370,7 @@ class JwtsTest {
|
|||
.setExpiration(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getExpiration()
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,7 @@ class JwtsTest {
|
|||
void testConvenienceNotBefore() {
|
||||
Date now = now() //jwt exp only supports *seconds* since epoch:
|
||||
String compact = Jwts.builder().setNotBefore(now).compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
def claimedDate = claims.getNotBefore()
|
||||
assertEquals now, claimedDate
|
||||
|
||||
|
@ -387,7 +387,7 @@ class JwtsTest {
|
|||
.setNotBefore(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getNotBefore()
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,7 @@ class JwtsTest {
|
|||
void testConvenienceIssuedAt() {
|
||||
Date now = now() //jwt exp only supports *seconds* since epoch:
|
||||
String compact = Jwts.builder().setIssuedAt(now).compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
def claimedDate = claims.getIssuedAt()
|
||||
assertEquals now, claimedDate
|
||||
|
||||
|
@ -404,7 +404,7 @@ class JwtsTest {
|
|||
.setIssuedAt(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getIssuedAt()
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ class JwtsTest {
|
|||
void testConvenienceId() {
|
||||
String id = UUID.randomUUID().toString()
|
||||
String compact = Jwts.builder().setId(id).compact()
|
||||
Claims claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertEquals id, claims.getId()
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
|
@ -420,7 +420,7 @@ class JwtsTest {
|
|||
.setId(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parserBuilder().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
assertNull claims.getId()
|
||||
}
|
||||
|
||||
|
@ -435,7 +435,7 @@ class JwtsTest {
|
|||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(key, alg)
|
||||
.claim("state", "hello this is an amazing jwt").compact()
|
||||
|
||||
def jws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
def jws = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.payload
|
||||
|
||||
|
@ -457,7 +457,7 @@ class JwtsTest {
|
|||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(key, alg)
|
||||
.claim("state", "hello this is an amazing jwt").compressWith(Jwts.ZIP.DEF).compact()
|
||||
|
||||
def jws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
def jws = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.payload
|
||||
|
||||
|
@ -479,7 +479,7 @@ class JwtsTest {
|
|||
String compact = Jwts.builder().setId(id).setAudience("an audience").signWith(key, alg)
|
||||
.claim("state", "hello this is an amazing jwt").compressWith(Jwts.ZIP.GZIP).compact()
|
||||
|
||||
def jws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
def jws = Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
|
||||
Claims claims = jws.payload
|
||||
|
||||
|
@ -506,7 +506,7 @@ class JwtsTest {
|
|||
}
|
||||
}).compact()
|
||||
|
||||
def jws = Jwts.parserBuilder().setSigningKey(key).setCompressionCodecResolver(new CompressionCodecResolver() {
|
||||
def jws = Jwts.parser().setSigningKey(key).setCompressionCodecResolver(new CompressionCodecResolver() {
|
||||
@Override
|
||||
CompressionCodec resolveCompressionCodec(Header header) throws CompressionException {
|
||||
String algorithm = header.getCompressionAlgorithm()
|
||||
|
@ -545,7 +545,7 @@ class JwtsTest {
|
|||
}
|
||||
}).compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwts.parser().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -559,7 +559,7 @@ class JwtsTest {
|
|||
String compact = Jwts.builder().setPayload(payload).signWith(key, alg)
|
||||
.compressWith(Jwts.ZIP.DEF).compact()
|
||||
|
||||
def jws = Jwts.parserBuilder().setSigningKey(key).build().parseContentJws(compact)
|
||||
def jws = Jwts.parser().setSigningKey(key).build().parseContentJws(compact)
|
||||
|
||||
assertEquals "DEF", jws.header.getCompressionAlgorithm()
|
||||
|
||||
|
@ -678,7 +678,7 @@ class JwtsTest {
|
|||
|
||||
String jws = Jwts.builder().setSubject("Foo").signWith(key, alg).compact()
|
||||
|
||||
Jwts.parserBuilder().setSigningKey(weakKey).build().parseClaimsJws(jws)
|
||||
Jwts.parser().setSigningKey(weakKey).build().parseClaimsJws(jws)
|
||||
fail('parseClaimsJws must fail for weak keys')
|
||||
}
|
||||
|
||||
|
@ -722,7 +722,7 @@ class JwtsTest {
|
|||
void testParserWithMismatchedEllipticCurveKeyAndAlgorithm() {
|
||||
def pair = TestKeys.ES256.pair
|
||||
def jws = Jwts.builder().setSubject('foo').signWith(pair.private).compact()
|
||||
def parser = Jwts.parserBuilder().setSigningKey(TestKeys.ES384.pair.public).build()
|
||||
def parser = Jwts.parser().setSigningKey(TestKeys.ES384.pair.public).build()
|
||||
try {
|
||||
parser.parseClaimsJws(jws)
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
|
@ -745,7 +745,7 @@ class JwtsTest {
|
|||
def invalidEncodedSignature = "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ"
|
||||
String jws = withoutSignature + '.' + invalidEncodedSignature
|
||||
def keypair = Jwts.SIG.ES256.keyPairBuilder().build()
|
||||
Jwts.parserBuilder().setSigningKey(keypair.public).build().parseClaimsJws(jws)
|
||||
Jwts.parser().setSigningKey(keypair.public).build().parseClaimsJws(jws)
|
||||
}
|
||||
|
||||
//Asserts correct/expected behavior discussed in https://github.com/jwtk/jjwt/issues/20
|
||||
|
@ -759,7 +759,7 @@ class JwtsTest {
|
|||
String notSigned = Jwts.builder().setSubject("Foo").compact()
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(notSigned)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(notSigned)
|
||||
fail('parseClaimsJws must fail for unsigned JWTs')
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertEquals 'Unprotected Claims JWTs are not supported.', expected.message
|
||||
|
@ -775,7 +775,7 @@ class JwtsTest {
|
|||
def c = base64Url('{"sub":"joe"}')
|
||||
def compact = h + '.ecek.iv.' + c + '.tag'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
assertEquals DefaultJwtParser.MISSING_JWE_ALG_MSG, e.getMessage()
|
||||
|
@ -791,7 +791,7 @@ class JwtsTest {
|
|||
def c = base64Url('{"sub":"joe"}')
|
||||
def compact = h + '.ecek.iv.' + c + '.tag'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
assertEquals DefaultJwtParser.MISSING_JWE_ALG_MSG, e.getMessage()
|
||||
|
@ -807,7 +807,7 @@ class JwtsTest {
|
|||
def c = base64Url('{"sub":"joe"}')
|
||||
def compact = h + '.ecek.iv.' + c + '.tag'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(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.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
assertEquals DefaultJwtParser.JWE_NONE_MSG, e.getMessage()
|
||||
|
@ -839,7 +839,7 @@ class JwtsTest {
|
|||
def c = base64Url('{"sub":"joe"}')
|
||||
def compact = h + '.ecek.iv.' + c + '.'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = String.format(DefaultJwtParser.MISSING_JWE_DIGEST_MSG_FMT, 'dir')
|
||||
|
@ -858,7 +858,7 @@ class JwtsTest {
|
|||
def tag = '&'
|
||||
def compact = h + '.IA==.IA==.' + c + '.' + tag
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = 'Compact JWE strings must always contain an AAD Authentication Tag.'
|
||||
|
@ -874,7 +874,7 @@ class JwtsTest {
|
|||
def h = base64Url('{"alg":"dir","enc":"A128GCM"}')
|
||||
def compact = h + '.ecek.iv..tag'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = 'Compact JWE strings MUST always contain a payload (ciphertext).'
|
||||
|
@ -893,7 +893,7 @@ class JwtsTest {
|
|||
def encodedKey = '&'
|
||||
def compact = h + '.' + encodedKey + '.iv.' + c + '.tag'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = 'Compact JWE string represents an encrypted key, but the key is empty.'
|
||||
|
@ -910,7 +910,7 @@ class JwtsTest {
|
|||
def c = base64Url('{"sub":"joe"}')
|
||||
def compact = h + '.IA==..' + c + '.tag'
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
String expected = 'Compact JWE strings must always contain an Initialization Vector.'
|
||||
|
@ -930,7 +930,7 @@ class JwtsTest {
|
|||
def tag = 'IA=='
|
||||
def compact = "$h.$ekey.$iv.$c.$tag" as String
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (MalformedJwtException e) {
|
||||
assertEquals DefaultJwtParser.MISSING_ENC_MSG, e.getMessage()
|
||||
|
@ -949,7 +949,7 @@ class JwtsTest {
|
|||
def tag = 'IA=='
|
||||
def compact = "$h.$ekey.$iv.$c.$tag" as String
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String expected = "Unrecognized JWE 'enc' (Encryption Algorithm) header value: foo"
|
||||
|
@ -969,7 +969,7 @@ class JwtsTest {
|
|||
def tag = 'IA=='
|
||||
def compact = "$h.$ekey.$iv.$c.$tag" as String
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String expected = "Unrecognized JWE 'alg' (Algorithm) header value: bar"
|
||||
|
@ -987,7 +987,7 @@ class JwtsTest {
|
|||
def sig = 'IA=='
|
||||
def compact = "$h.$c.$sig" as String
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJws(compact)
|
||||
Jwts.parser().build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (io.jsonwebtoken.security.SignatureException e) {
|
||||
String expected = "Unsupported signature algorithm 'bar'"
|
||||
|
@ -1007,7 +1007,7 @@ class JwtsTest {
|
|||
def tag = 'IA=='
|
||||
def compact = "$h.$ekey.$iv.$c.$tag" as String
|
||||
try {
|
||||
Jwts.parserBuilder().build().parseClaimsJwe(compact)
|
||||
Jwts.parser().build().parseClaimsJwe(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String expected = "Cannot decrypt JWE payload: unable to locate key for JWE with header: {alg=dir, enc=A128GCM}"
|
||||
|
@ -1052,7 +1052,7 @@ class JwtsTest {
|
|||
|
||||
def jws = Jwts.builder().setSubject("joe").signWith(key, alg).compact()
|
||||
|
||||
assertEquals 'joe', Jwts.parserBuilder()
|
||||
assertEquals 'joe', Jwts.parser()
|
||||
.addSignatureAlgorithms([alg])
|
||||
.setSigningKey(key)
|
||||
.build()
|
||||
|
@ -1096,7 +1096,7 @@ class JwtsTest {
|
|||
|
||||
def jwe = Jwts.builder().setSubject("joe").encryptWith(key, encAlg).compact()
|
||||
|
||||
assertEquals 'joe', Jwts.parserBuilder()
|
||||
assertEquals 'joe', Jwts.parser()
|
||||
.addEncryptionAlgorithms([encAlg])
|
||||
.decryptWith(key)
|
||||
.build()
|
||||
|
@ -1134,7 +1134,7 @@ class JwtsTest {
|
|||
}
|
||||
|
||||
try {
|
||||
Jwts.parserBuilder()
|
||||
Jwts.parser()
|
||||
.setKeyLocator(new ConstantKeyLocator(TestKeys.HS256, TestKeys.A128GCM))
|
||||
.addKeyAlgorithms([badKeyAlg]) // <-- add bad alg here
|
||||
.build()
|
||||
|
@ -1154,7 +1154,7 @@ class JwtsTest {
|
|||
void testParseRequiredInt() {
|
||||
def key = TestKeys.HS256
|
||||
def jws = Jwts.builder().signWith(key).claim("foo", 42).compact()
|
||||
Jwts.parserBuilder().setSigningKey(key)
|
||||
Jwts.parser().setSigningKey(key)
|
||||
.require("foo", 42L) //require a long, but jws contains int, should still work
|
||||
.build().parseClaimsJws(jws)
|
||||
}
|
||||
|
@ -1178,14 +1178,14 @@ class JwtsTest {
|
|||
String forged = Jwts.builder().setSubject("Not Joe").compact()
|
||||
|
||||
//assert that our forged header has a 'NONE' algorithm:
|
||||
assertEquals 'none', Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(forged).getHeader().get('alg')
|
||||
assertEquals 'none', Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(forged).getHeader().get('alg')
|
||||
|
||||
//now let's forge it by appending the signature the server expects:
|
||||
forged += signature
|
||||
|
||||
//now assert that, when the server tries to parse the forged token, parsing fails:
|
||||
try {
|
||||
Jwts.parserBuilder().enableUnsecuredJws().setSigningKey(key).build().parse(forged)
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parse(forged)
|
||||
fail("Parsing must fail for a forged token.")
|
||||
} catch (MalformedJwtException expected) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', expected.message
|
||||
|
@ -1217,7 +1217,7 @@ class JwtsTest {
|
|||
|
||||
// Assert that the server (that should always use the private key) does not recognized the forged token:
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(privateKey).build().parse(forged)
|
||||
Jwts.parser().setSigningKey(privateKey).build().parse(forged)
|
||||
fail("Forged token must not be successfully parsed.")
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertTrue expected.getMessage().startsWith('The parsed JWT indicates it was signed with the')
|
||||
|
@ -1249,7 +1249,7 @@ class JwtsTest {
|
|||
|
||||
// Assert that the parser does not recognized the forged token:
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(publicKey).build().parse(forged)
|
||||
Jwts.parser().setSigningKey(publicKey).build().parse(forged)
|
||||
fail("Forged token must not be successfully parsed.")
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertTrue expected.getMessage().startsWith('The parsed JWT indicates it was signed with the')
|
||||
|
@ -1281,7 +1281,7 @@ class JwtsTest {
|
|||
|
||||
// Assert that the parser does not recognized the forged token:
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(publicKey).build().parse(forged)
|
||||
Jwts.parser().setSigningKey(publicKey).build().parse(forged)
|
||||
fail("Forged token must not be successfully parsed.")
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertTrue expected.getMessage().startsWith('The parsed JWT indicates it was signed with the')
|
||||
|
@ -1310,7 +1310,7 @@ class JwtsTest {
|
|||
.compact()
|
||||
|
||||
//decrypt:
|
||||
def jwt = Jwts.parserBuilder()
|
||||
def jwt = Jwts.parser()
|
||||
.decryptWith(key)
|
||||
.build()
|
||||
.parseClaimsJwe(jwe)
|
||||
|
@ -1338,7 +1338,7 @@ class JwtsTest {
|
|||
.compact()
|
||||
|
||||
//decompress and decrypt:
|
||||
def jwt = Jwts.parserBuilder()
|
||||
def jwt = Jwts.parser()
|
||||
.decryptWith(key)
|
||||
.build()
|
||||
.parseClaimsJwe(jwe)
|
||||
|
@ -1367,7 +1367,7 @@ class JwtsTest {
|
|||
.compact()
|
||||
|
||||
//decrypt:
|
||||
def jwt = Jwts.parserBuilder()
|
||||
def jwt = Jwts.parser()
|
||||
.decryptWith(key)
|
||||
.build()
|
||||
.parseClaimsJwe(jwe)
|
||||
|
@ -1388,7 +1388,7 @@ class JwtsTest {
|
|||
.compact()
|
||||
|
||||
//decrypt:
|
||||
def jwt = Jwts.parserBuilder()
|
||||
def jwt = Jwts.parser()
|
||||
.decryptWith(key)
|
||||
.build()
|
||||
.parseClaimsJwe(jwe)
|
||||
|
@ -1421,7 +1421,7 @@ class JwtsTest {
|
|||
.compact()
|
||||
|
||||
//decrypt:
|
||||
def jwt = Jwts.parserBuilder()
|
||||
def jwt = Jwts.parser()
|
||||
.decryptWith(privKey)
|
||||
.build()
|
||||
.parseClaimsJwe(jwe)
|
||||
|
@ -1456,7 +1456,7 @@ class JwtsTest {
|
|||
.compact()
|
||||
|
||||
//decrypt:
|
||||
def jwt = Jwts.parserBuilder()
|
||||
def jwt = Jwts.parser()
|
||||
.decryptWith(privKey)
|
||||
.build()
|
||||
.parseClaimsJwe(jwe)
|
||||
|
@ -1560,7 +1560,7 @@ class JwtsTest {
|
|||
}
|
||||
|
||||
static Jwe<Claims> decrypt(String jwe, PrivateKey key) {
|
||||
return Jwts.parserBuilder().decryptWith(key).build().parseClaimsJwe(jwe)
|
||||
return Jwts.parser().decryptWith(key).build().parseClaimsJwe(jwe)
|
||||
}
|
||||
|
||||
static void testRsa(io.jsonwebtoken.security.SignatureAlgorithm alg, boolean verifyWithPrivateKey = false) {
|
||||
|
@ -1578,7 +1578,7 @@ class JwtsTest {
|
|||
key = privateKey
|
||||
}
|
||||
|
||||
def token = Jwts.parserBuilder().verifyWith(key).build().parse(jwt)
|
||||
def token = Jwts.parser().verifyWith(key).build().parse(jwt)
|
||||
|
||||
assertEquals([alg: alg.getId()], token.header)
|
||||
assertEquals(claims, token.payload)
|
||||
|
@ -1593,7 +1593,7 @@ class JwtsTest {
|
|||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(key, alg).compact()
|
||||
|
||||
def token = Jwts.parserBuilder().verifyWith(key).build().parse(jwt)
|
||||
def token = Jwts.parser().verifyWith(key).build().parse(jwt)
|
||||
|
||||
assertEquals([alg: alg.getId()], token.header)
|
||||
assertEquals(claims, token.payload)
|
||||
|
@ -1614,7 +1614,7 @@ class JwtsTest {
|
|||
key = privateKey
|
||||
}
|
||||
|
||||
def token = Jwts.parserBuilder().verifyWith(key).build().parse(jwt)
|
||||
def token = Jwts.parser().verifyWith(key).build().parse(jwt)
|
||||
|
||||
assertEquals([alg: alg.getId()], token.header)
|
||||
assertEquals(claims, token.payload)
|
||||
|
|
|
@ -32,7 +32,7 @@ class RsaSigningKeyResolverAdapterTest {
|
|||
|
||||
def compact = Jwts.builder().claim('foo', 'bar').signWith(pair.private, alg).compact()
|
||||
|
||||
Jws<Claims> jws = Jwts.parserBuilder().setSigningKey(pair.public).build().parseClaimsJws(compact)
|
||||
Jws<Claims> jws = Jwts.parser().setSigningKey(pair.public).build().parseClaimsJws(compact)
|
||||
|
||||
try {
|
||||
new SigningKeyResolverAdapter().resolveSigningKey(jws.header, jws.payload)
|
||||
|
|
|
@ -30,7 +30,7 @@ class DefaultJweTest {
|
|||
def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm
|
||||
def key = alg.keyBuilder().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact()
|
||||
def jwe = Jwts.parserBuilder().decryptWith(key).build().parseClaimsJwe(compact)
|
||||
def jwe = Jwts.parser().decryptWith(key).build().parseClaimsJwe(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"
|
||||
|
@ -42,7 +42,7 @@ class DefaultJweTest {
|
|||
def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm
|
||||
def key = alg.keyBuilder().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact()
|
||||
def parser = Jwts.parserBuilder().decryptWith(key).build()
|
||||
def parser = Jwts.parser().decryptWith(key).build()
|
||||
def jwe1 = parser.parseClaimsJwe(compact)
|
||||
def jwe2 = parser.parseClaimsJwe(compact)
|
||||
assertNotEquals jwe1, 'hello' as String
|
||||
|
|
|
@ -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.parserBuilder().verifyWith(key).build().parseClaimsJws(compact)
|
||||
def jws = Jwts.parser().verifyWith(key).build().parseClaimsJws(compact)
|
||||
assertEquals 'header={alg=HS256},payload={foo=bar},signature=' + signature, jws.toString()
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ class DefaultJwsTest {
|
|||
def alg = Jwts.SIG.HS256
|
||||
def key = alg.keyBuilder().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
|
||||
def parser = Jwts.parserBuilder().verifyWith(key).build()
|
||||
def parser = Jwts.parser().verifyWith(key).build()
|
||||
def jws1 = parser.parseClaimsJws(compact)
|
||||
def jws2 = parser.parseClaimsJws(compact)
|
||||
assertNotEquals jws1, 'hello' as String
|
||||
|
|
|
@ -444,7 +444,7 @@ class DefaultJwtBuilderTest {
|
|||
.claim('foo', 'bar')
|
||||
.compact()
|
||||
|
||||
assertEquals 'bar', Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jws).getPayload().get('foo')
|
||||
assertEquals 'bar', Jwts.parser().setSigningKey(key).build().parseClaimsJws(jws).getPayload().get('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -476,7 +476,7 @@ class DefaultJwtBuilderTest {
|
|||
def enc = Jwts.ENC.A128GCM
|
||||
def key = enc.keyBuilder().build()
|
||||
def jwe = builder.setPayload("me").encryptWith(key, enc).compact()
|
||||
def jwt = Jwts.parserBuilder().decryptWith(key).build().parseContentJwe(jwe)
|
||||
def jwt = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe)
|
||||
assertEquals 'me', new String(jwt.getPayload(), StandardCharsets.UTF_8)
|
||||
}
|
||||
|
||||
|
@ -485,7 +485,7 @@ class DefaultJwtBuilderTest {
|
|||
def enc = Jwts.ENC.A128GCM
|
||||
def key = enc.keyBuilder().build()
|
||||
def jwe = builder.setSubject('joe').encryptWith(key, enc).compact()
|
||||
def jwt = Jwts.parserBuilder().decryptWith(key).build().parseClaimsJwe(jwe)
|
||||
def jwt = Jwts.parser().decryptWith(key).build().parseClaimsJwe(jwe)
|
||||
assertEquals 'joe', jwt.getPayload().getSubject()
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package io.jsonwebtoken.impl
|
|||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.jsonwebtoken.*
|
||||
import io.jsonwebtoken.impl.security.ConstantKeyLocator
|
||||
import io.jsonwebtoken.impl.security.LocatingKeyResolver
|
||||
import io.jsonwebtoken.impl.security.TestKeys
|
||||
import io.jsonwebtoken.io.Decoder
|
||||
import io.jsonwebtoken.io.DecodingException
|
||||
|
@ -54,10 +55,24 @@ class DefaultJwtParserBuilderTest {
|
|||
|
||||
def parser = builder.setProvider(provider).build()
|
||||
|
||||
assertSame provider, parser.jwtParser.provider
|
||||
assertSame provider, parser.provider
|
||||
verify provider
|
||||
}
|
||||
|
||||
@Test
|
||||
void testKeyLocatorAndVerificationKeyConfigured() {
|
||||
try {
|
||||
builder
|
||||
.setKeyLocator(new ConstantKeyLocator(null, null))
|
||||
.verifyWith(TestKeys.HS256)
|
||||
.build()
|
||||
fail()
|
||||
} catch (IllegalStateException e) {
|
||||
String msg = "Both 'keyLocator' and a 'verifyWith' key cannot be configured. Prefer 'keyLocator' if possible."
|
||||
assertEquals msg, e.getMessage()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testKeyLocatorAndDecryptionKeyConfigured() {
|
||||
try {
|
||||
|
@ -67,7 +82,7 @@ class DefaultJwtParserBuilderTest {
|
|||
.build()
|
||||
fail()
|
||||
} catch (IllegalStateException e) {
|
||||
String msg = "Both 'keyLocator' and 'decryptWith' key cannot be configured. Prefer 'keyLocator' if possible."
|
||||
String msg = "Both 'keyLocator' and a 'decryptWith' key cannot be configured. Prefer 'keyLocator' if possible."
|
||||
assertEquals msg, e.getMessage()
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +100,7 @@ class DefaultJwtParserBuilderTest {
|
|||
return null
|
||||
}
|
||||
}
|
||||
def b = builder.base64UrlDecodeWith(decoder)
|
||||
def b = builder.base64UrlDecodeWith(decoder).build()
|
||||
assertSame decoder, b.base64UrlDecoder
|
||||
}
|
||||
|
||||
|
@ -139,7 +154,7 @@ class DefaultJwtParserBuilderTest {
|
|||
}
|
||||
}
|
||||
def parser = builder.setCompressionCodecResolver(resolver).build()
|
||||
assertSame resolver, parser.jwtParser.compressionAlgorithmLocator.resolver
|
||||
assertSame resolver, parser.zipAlgFn.resolver
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -147,7 +162,7 @@ class DefaultJwtParserBuilderTest {
|
|||
def codec = new TestCompressionCodec(id: 'test')
|
||||
def parser = builder.addCompressionAlgorithms([codec] as Set<CompressionCodec>).build()
|
||||
def header = Jwts.header().setCompressionAlgorithm(codec.getId()).build()
|
||||
assertSame codec, parser.jwtParser.compressionAlgorithmLocator.locate(header)
|
||||
assertSame codec, parser.zipAlgFn.locate(header)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -203,10 +218,7 @@ class DefaultJwtParserBuilderTest {
|
|||
@Test
|
||||
void testDefaultDeserializer() {
|
||||
JwtParser parser = builder.build()
|
||||
assertThat parser.jwtParser.deserializer, CoreMatchers.instanceOf(JwtDeserializer)
|
||||
|
||||
// TODO: When the ImmutableJwtParser replaces the default implementation this test will need updating, something like:
|
||||
// assertThat parser.deserializer, CoreMatchers.instanceOf(JwtDeserializer)
|
||||
assertThat parser.deserializer, CoreMatchers.instanceOf(JwtDeserializer)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -214,20 +226,19 @@ class DefaultJwtParserBuilderTest {
|
|||
Deserializer deserializer = niceMock(Deserializer)
|
||||
JwtParser parser = builder.deserializeJsonWith(deserializer).build()
|
||||
|
||||
// TODO: When the ImmutableJwtParser replaces the default implementation this test will need updating
|
||||
assertThat parser.jwtParser.deserializer, CoreMatchers.instanceOf(JwtDeserializer)
|
||||
assertSame deserializer, parser.jwtParser.deserializer.deserializer
|
||||
assertThat parser.deserializer, CoreMatchers.instanceOf(JwtDeserializer)
|
||||
assertSame deserializer, parser.deserializer.deserializer
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerificationKeyAndSigningKeyResolverBothConfigured() {
|
||||
def key = TestKeys.HS256
|
||||
builder.verifyWith(key).setSigningKeyResolver(new ConstantKeyLocator(key, null))
|
||||
builder.verifyWith(key).setSigningKeyResolver(new LocatingKeyResolver(new ConstantKeyLocator(key, null)))
|
||||
try {
|
||||
builder.build()
|
||||
fail()
|
||||
} catch (IllegalStateException expected) {
|
||||
String msg = "Both 'signingKeyResolver and 'verifyWith/signWith' key cannot be configured. " + "Choose either, or prefer `keyLocator` when possible."
|
||||
String msg = "Both a 'signingKeyResolver and a 'verifyWith' key cannot be configured. " + "Choose either, or prefer `keyLocator` when possible."
|
||||
assertEquals(msg, expected.getMessage())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,9 @@ import io.jsonwebtoken.Jwts
|
|||
import io.jsonwebtoken.MalformedJwtException
|
||||
import io.jsonwebtoken.SignatureAlgorithm
|
||||
import io.jsonwebtoken.impl.lang.Bytes
|
||||
import io.jsonwebtoken.io.*
|
||||
import io.jsonwebtoken.io.DeserializationException
|
||||
import io.jsonwebtoken.io.Deserializer
|
||||
import io.jsonwebtoken.io.Encoders
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import io.jsonwebtoken.security.Keys
|
||||
import org.junit.Test
|
||||
|
@ -42,31 +44,13 @@ class DefaultJwtParserTest {
|
|||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testBase64UrlDecodeWithNullArgument() {
|
||||
new DefaultJwtParser().base64UrlDecodeWith(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBase64UrlDecodeWithCustomDecoder() {
|
||||
def decoder = new Decoder() {
|
||||
@Override
|
||||
Object decode(Object o) throws DecodingException {
|
||||
return null
|
||||
}
|
||||
}
|
||||
def b = new DefaultJwtParser().base64UrlDecodeWith(decoder)
|
||||
assertSame decoder, b.base64UrlDecoder
|
||||
private DefaultJwtParser newParser() {
|
||||
return Jwts.parser().build() as DefaultJwtParser
|
||||
}
|
||||
|
||||
@Test(expected = MalformedJwtException)
|
||||
void testBase64UrlDecodeWithInvalidInput() {
|
||||
new DefaultJwtParser().base64UrlDecode('20:SLDKJF;3993;----', 'test')
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void testDeserializeJsonWithNullArgument() {
|
||||
new DefaultJwtParser().deserializeJsonWith(null)
|
||||
newParser().base64UrlDecode('20:SLDKJF;3993;----', 'test')
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -77,15 +61,16 @@ class DefaultJwtParserTest {
|
|||
return OBJECT_MAPPER.readValue(bytes, Map.class)
|
||||
}
|
||||
}
|
||||
def p = new DefaultJwtParser().deserializeJsonWith(deserializer)
|
||||
def pb = Jwts.parser().deserializeJsonWith(deserializer)
|
||||
def p = pb.build() as DefaultJwtParser
|
||||
assertTrue("Expected wrapping deserializer to be instance of JwtDeserializer", p.deserializer instanceof JwtDeserializer )
|
||||
assertSame deserializer, p.deserializer.deserializer
|
||||
|
||||
def key = Keys.secretKeyFor(SignatureAlgorithm.HS256)
|
||||
def key = Jwts.SIG.HS256.keyBuilder().build()
|
||||
|
||||
String jws = Jwts.builder().claim('foo', 'bar').signWith(key, SignatureAlgorithm.HS256).compact()
|
||||
String jws = Jwts.builder().claim('foo', 'bar').signWith(key, Jwts.SIG.HS256).compact()
|
||||
|
||||
assertEquals 'bar', p.setSigningKey(key).parseClaimsJws(jws).getPayload().get('foo')
|
||||
assertEquals 'bar', pb.verifyWith(key).build().parseClaimsJws(jws).getPayload().get('foo')
|
||||
}
|
||||
|
||||
@Test(expected = MalformedJwtException)
|
||||
|
@ -103,7 +88,7 @@ class DefaultJwtParserTest {
|
|||
|
||||
String invalidJws = compact + encodedSignature
|
||||
|
||||
new DefaultJwtParser().setSigningKey(key).parseClaimsJws(invalidJws)
|
||||
Jwts.parser().verifyWith(key).build().parseClaimsJws(invalidJws)
|
||||
}
|
||||
|
||||
@Test(expected = MalformedJwtException)
|
||||
|
@ -121,7 +106,7 @@ class DefaultJwtParserTest {
|
|||
|
||||
String invalidJws = compact + encodedSignature
|
||||
|
||||
new DefaultJwtParser().setSigningKey(key).parseClaimsJws(invalidJws)
|
||||
Jwts.parser().verifyWith(key).build().parseClaimsJwe(invalidJws)
|
||||
}
|
||||
|
||||
@Test(expected = MalformedJwtException)
|
||||
|
@ -139,24 +124,7 @@ class DefaultJwtParserTest {
|
|||
|
||||
String invalidJws = compact + encodedSignature
|
||||
|
||||
new DefaultJwtParser().setSigningKey(key).parseClaimsJws(invalidJws)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMaxAllowedClockSkewSeconds() {
|
||||
long max = Long.MAX_VALUE / 1000 as long
|
||||
new DefaultJwtParser().setAllowedClockSkewSeconds(max) // no exception should be thrown
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExceededAllowedClockSkewSeconds() {
|
||||
long value = Long.MAX_VALUE / 1000 as long
|
||||
value = value + 1L
|
||||
try {
|
||||
new DefaultJwtParser().setAllowedClockSkewSeconds(value)
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals DefaultJwtParserBuilder.MAX_CLOCK_SKEW_ILLEGAL_MSG, expected.message
|
||||
}
|
||||
Jwts.parser().verifyWith(key).build().parseClaimsJws(invalidJws)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -30,7 +30,7 @@ class DefaultJwtTest {
|
|||
@Test
|
||||
void testToString() {
|
||||
String compact = Jwts.builder().setHeaderParam('foo', 'bar').setAudience('jsmith').compact()
|
||||
Jwt jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwt jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
assertEquals 'header={foo=bar, alg=none},payload={aud=jsmith}', jwt.toString()
|
||||
}
|
||||
|
||||
|
@ -39,14 +39,14 @@ class DefaultJwtTest {
|
|||
byte[] bytes = 'hello JJWT'.getBytes(StandardCharsets.UTF_8)
|
||||
String encoded = Encoders.BASE64URL.encode(bytes)
|
||||
String compact = Jwts.builder().setHeaderParam('foo', 'bar').setContent(bytes).compact()
|
||||
Jwt jwt = Jwts.parserBuilder().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
Jwt jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
assertEquals "header={foo=bar, alg=none},payload=$encoded" as String, jwt.toString()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEqualsAndHashCode() {
|
||||
String compact = Jwts.builder().claim('foo', 'bar').compact()
|
||||
def parser = Jwts.parserBuilder().enableUnsecuredJws().build()
|
||||
def parser = Jwts.parser().enableUnsecuredJws().build()
|
||||
def jwt1 = parser.parseClaimsJwt(compact)
|
||||
def jwt2 = parser.parseClaimsJwt(compact)
|
||||
assertNotEquals jwt1, 'hello' as String
|
||||
|
@ -60,7 +60,7 @@ class DefaultJwtTest {
|
|||
@Test
|
||||
void testBodyAndPayloadSame() {
|
||||
String compact = Jwts.builder().claim('foo', 'bar').compact()
|
||||
def parser = Jwts.parserBuilder().enableUnsecuredJws().build()
|
||||
def parser = Jwts.parser().enableUnsecuredJws().build()
|
||||
def jwt1 = parser.parseClaimsJwt(compact)
|
||||
def jwt2 = parser.parseClaimsJwt(compact)
|
||||
assertEquals jwt1.getBody(), jwt1.getPayload()
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl
|
||||
|
||||
import io.jsonwebtoken.*
|
||||
import io.jsonwebtoken.io.Decoder
|
||||
import io.jsonwebtoken.io.Deserializer
|
||||
import org.junit.Test
|
||||
|
||||
import java.security.Key
|
||||
|
||||
import static org.easymock.EasyMock.*
|
||||
import static org.hamcrest.CoreMatchers.is
|
||||
import static org.hamcrest.MatcherAssert.assertThat
|
||||
|
||||
/**
|
||||
* TODO: These mutable methods will be removed pre 1.0, and ImmutableJwtParser will be replaced with the default
|
||||
* JwtParser impl.
|
||||
*
|
||||
* @since 0.11.0
|
||||
*/
|
||||
class ImmutableJwtParserTest {
|
||||
|
||||
@Test
|
||||
void parseWithHandlerTest() {
|
||||
|
||||
def jwtString = "j.w.t"
|
||||
JwtHandler jwtHandler = mock(JwtHandler)
|
||||
JwtParser jwtParser = mock(JwtParser)
|
||||
Object returnValue = new Object()
|
||||
|
||||
expect(jwtParser.parse(jwtString, jwtHandler)).andReturn(returnValue)
|
||||
replay(jwtParser)
|
||||
|
||||
assertThat new ImmutableJwtParser(jwtParser).parse(jwtString, jwtHandler), is(returnValue)
|
||||
|
||||
verify(jwtParser)
|
||||
}
|
||||
|
||||
private ImmutableJwtParser jwtParser() {
|
||||
return new ImmutableJwtParser(mock(JwtParser))
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireIdTest() {
|
||||
jwtParser().requireId("id")
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireSubjectTest() {
|
||||
jwtParser().requireSubject("subject")
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireAudienceTest() {
|
||||
jwtParser().requireAudience("aud")
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireIssuerTest() {
|
||||
jwtParser().requireIssuer("issuer")
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireIssuedAtTest() {
|
||||
jwtParser().requireIssuedAt(new Date())
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireExpirationTest() {
|
||||
jwtParser().requireExpiration(new Date())
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireNotBeforeTest() {
|
||||
jwtParser().requireNotBefore(new Date())
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void requireTest() {
|
||||
jwtParser().require("key", "value")
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setClockTest() {
|
||||
jwtParser().setClock(mock((Clock)))
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setAllowedClockSkewSecondsTest() {
|
||||
jwtParser().setAllowedClockSkewSeconds(1L)
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setSigningKeyBytesTest() {
|
||||
jwtParser().setSigningKey("foo".getBytes())
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setSigningKeyStringTest() {
|
||||
jwtParser().setSigningKey("foo")
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setSigningKey() {
|
||||
jwtParser().setSigningKey(mock(Key))
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setSigningKeyResolverTest() {
|
||||
jwtParser().setSigningKeyResolver(mock(SigningKeyResolver))
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void setCompressionCodecResolverTest() {
|
||||
jwtParser().setCompressionCodecResolver(mock(CompressionCodecResolver))
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void base64UrlDecodeWithTest() {
|
||||
jwtParser().base64UrlDecodeWith(mock(Decoder))
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException)
|
||||
void deserializeJsonWithTest() {
|
||||
jwtParser().deserializeJsonWith(mock(Deserializer))
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ class DeflateCompressionCodecTest {
|
|||
@Test
|
||||
void testBackwardsCompatibility_0_10_6() {
|
||||
final String jwtFrom0106 = 'eyJhbGciOiJub25lIiwiemlwIjoiREVGIn0.eNqqVsosLlayUspNVdJRKi5NAjJLi1OLgJzMxBIlK0sTMzMLEwsDAx2l1IoCJSsTQwMjExOQQC0AAAD__w.'
|
||||
Jwts.parserBuilder().enableUnsecuredJws().enableUnsecuredDecompression().build().parseClaimsJwt(jwtFrom0106) // no exception should be thrown
|
||||
Jwts.parser().enableUnsecuredJws().enableUnsecuredDecompression().build().parseClaimsJwt(jwtFrom0106) // no exception should be thrown
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl.lang
|
||||
|
||||
import io.jsonwebtoken.lang.UnknownClassException
|
||||
import org.junit.Test
|
||||
|
||||
class LegacyServicesTest {
|
||||
|
||||
@Test(expected = UnknownClassException)
|
||||
void serviceNotFoundTest() {
|
||||
// try to load a class that will NOT have any services, i.e. this test class.
|
||||
LegacyServices.loadFirst(LegacyServicesTest)
|
||||
}
|
||||
}
|
|
@ -138,7 +138,7 @@ class EdSignatureAlgorithmTest {
|
|||
|
||||
static void testSig(SignatureAlgorithm alg, PrivateKey signing, PublicKey verification) {
|
||||
String jwt = Jwts.builder().setIssuer('me').setAudience('you').signWith(signing, alg).compact()
|
||||
def token = Jwts.parserBuilder().verifyWith(verification).build().parseClaimsJws(jwt)
|
||||
def token = Jwts.parser().verifyWith(verification).build().parseClaimsJws(jwt)
|
||||
assertEquals([alg: alg.getId()], token.header)
|
||||
assertEquals 'me', token.getPayload().getIssuer()
|
||||
assertEquals 'you', token.getPayload().getAudience()
|
||||
|
|
|
@ -56,7 +56,7 @@ class Issue542Test {
|
|||
for (alg in algs) {
|
||||
PublicKey key = TestKeys.forAlgorithm(alg).pair.public
|
||||
String jws = JWS_0_10_7_VALUES[alg]
|
||||
def token = Jwts.parserBuilder().verifyWith(key).build().parseClaimsJws(jws)
|
||||
def token = Jwts.parser().verifyWith(key).build().parseClaimsJws(jws)
|
||||
assert 'joe' == token.payload.getIssuer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ class RFC7516AppendixA1Test {
|
|||
RsaPrivateJwk jwk = Jwks.builder().set(KEK_VALUES).build() as RsaPrivateJwk
|
||||
RSAPrivateKey privKey = jwk.toKey()
|
||||
|
||||
Jwe<byte[]> jwe = Jwts.parserBuilder().decryptWith(privKey).build().parseContentJwe(COMPLETE_JWE)
|
||||
Jwe<byte[]> jwe = Jwts.parser().decryptWith(privKey).build().parseContentJwe(COMPLETE_JWE)
|
||||
assertEquals PLAINTEXT, new String(jwe.getPayload(), StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ class RFC7516AppendixA2Test {
|
|||
RsaPrivateJwk jwk = Jwks.builder().set(KEK_VALUES).build() as RsaPrivateJwk
|
||||
RSAPrivateKey privKey = jwk.toKey()
|
||||
|
||||
Jwe<byte[]> jwe = Jwts.parserBuilder().decryptWith(privKey).build().parseContentJwe(COMPLETE_JWE)
|
||||
Jwe<byte[]> jwe = Jwts.parser().decryptWith(privKey).build().parseContentJwe(COMPLETE_JWE)
|
||||
assertEquals PLAINTEXT, new String(jwe.getPayload(), StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ class RFC7516AppendixA3Test {
|
|||
SecretKey kek = jwk.toKey()
|
||||
|
||||
// test decryption per the RFC
|
||||
Jwe<byte[]> jwe = Jwts.parserBuilder().decryptWith(kek).build().parseContentJwe(COMPLETE_JWE)
|
||||
Jwe<byte[]> jwe = Jwts.parser().decryptWith(kek).build().parseContentJwe(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),
|
||||
|
|
|
@ -331,7 +331,7 @@ class RFC7517AppendixCTest {
|
|||
assertEquals RFC_COMPACT_JWE, compact
|
||||
|
||||
//ensure we can decrypt now:
|
||||
Jwe<byte[]> jwe = Jwts.parserBuilder().decryptWith(key).build().parseContentJwe(compact)
|
||||
Jwe<byte[]> jwe = Jwts.parser().decryptWith(key).build().parseContentJwe(compact)
|
||||
|
||||
assertEquals RFC_JWK_JSON, new String(jwe.getPayload(), StandardCharsets.UTF_8)
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ class RFC7518AppendixCTest {
|
|||
assertArrayEquals RFC_DERIVED_KEY, derivedKey
|
||||
|
||||
// now reverse the process and ensure it all works:
|
||||
Jwe<Claims> claimsJwe = Jwts.parserBuilder()
|
||||
Jwe<Claims> claimsJwe = Jwts.parser()
|
||||
.decryptWith(bobJwk.toKey())
|
||||
.build().parseClaimsJwe(jwe)
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ class RFC7520Section4Test {
|
|||
assertEquals FIGURE_13, result
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().verifyWith(jwk.toPublicJwk().toKey()).build().parseContentJws(result)
|
||||
def parsed = Jwts.parser().verifyWith(jwk.toPublicJwk().toKey()).build().parseContentJws(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 {
|
|||
|
||||
// even though we can't know what the signature output is ahead of time due to random data, we can assert
|
||||
// the signature to guarantee a round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder()
|
||||
def parsed = Jwts.parser()
|
||||
.verifyWith(jwk.toPublicJwk().toKey())
|
||||
.build().parseContentJws(result)
|
||||
|
||||
|
@ -316,7 +316,7 @@ class RFC7520Section4Test {
|
|||
|
||||
// even though we can't know what the signature output is ahead of time due to random data, we can assert
|
||||
// the signature to guarantee a round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder()
|
||||
def parsed = Jwts.parser()
|
||||
.verifyWith(jwk.toPublicJwk().toKey())
|
||||
.build().parseContentJws(result)
|
||||
|
||||
|
@ -357,7 +357,7 @@ class RFC7520Section4Test {
|
|||
assertEquals FIGURE_34, result
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().verifyWith(key).build().parseContentJws(result)
|
||||
def parsed = Jwts.parser().verifyWith(key).build().parseContentJws(result)
|
||||
assertEquals alg.getId(), parsed.header.getAlgorithm()
|
||||
assertEquals jwk.getId(), parsed.header.getKeyId()
|
||||
assertEquals FIGURE_7, utf8(parsed.payload)
|
||||
|
@ -398,7 +398,7 @@ class RFC7520Section4Test {
|
|||
assertEquals FIGURE_41, detached
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().verifyWith(key).build().parseContentJws(result)
|
||||
def parsed = Jwts.parser().verifyWith(key).build().parseContentJws(result)
|
||||
assertEquals alg.getId(), parsed.header.getAlgorithm()
|
||||
assertEquals jwk.getId(), parsed.header.getKeyId()
|
||||
assertEquals FIGURE_7, utf8(parsed.payload)
|
||||
|
|
|
@ -481,7 +481,7 @@ class RFC7520Section5Test {
|
|||
assertEquals FIGURE_81, result
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().decryptWith(jwk.toKey()).build().parseContentJwe(result)
|
||||
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseContentJwe(result)
|
||||
assertEquals alg.getId(), parsed.header.getAlgorithm()
|
||||
assertEquals jwk.getId(), parsed.header.getKeyId()
|
||||
assertEquals enc.getId(), parsed.header.getEncryptionAlgorithm()
|
||||
|
@ -545,7 +545,7 @@ class RFC7520Section5Test {
|
|||
assertEquals FIGURE_92, result
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().decryptWith(jwk.toKey()).build().parseContentJwe(result)
|
||||
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseContentJwe(result)
|
||||
assertEquals alg.getId(), parsed.header.getAlgorithm()
|
||||
assertEquals jwk.getId(), parsed.header.getKeyId()
|
||||
assertEquals enc.getId(), parsed.header.getEncryptionAlgorithm()
|
||||
|
@ -606,7 +606,7 @@ class RFC7520Section5Test {
|
|||
assertEquals FIGURE_105, result
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().decryptWith(key).build().parseContentJwe(result)
|
||||
def parsed = Jwts.parser().decryptWith(key).build().parseContentJwe(result)
|
||||
assertEquals alg.getId(), parsed.header.getAlgorithm()
|
||||
assertEquals FIGURE_99, b64Url(parsed.header.getPbes2Salt())
|
||||
assertEquals p2c, parsed.header.getPbes2Count()
|
||||
|
@ -668,7 +668,7 @@ class RFC7520Section5Test {
|
|||
assertEquals FIGURE_117, result
|
||||
|
||||
// Assert round trip works as expected:
|
||||
def parsed = Jwts.parserBuilder().decryptWith(jwk.toKey()).build().parseContentJwe(result)
|
||||
def parsed = Jwts.parser().decryptWith(jwk.toKey()).build().parseContentJwe(result)
|
||||
assertEquals alg.getId(), parsed.header.getAlgorithm()
|
||||
assertEquals enc.getId(), parsed.header.getEncryptionAlgorithm()
|
||||
assertEquals jwk.getId(), parsed.header.getKeyId()
|
||||
|
|
|
@ -108,7 +108,7 @@ class RFC8037AppendixATest {
|
|||
assertEquals A4_JWS_COMPACT, compact
|
||||
|
||||
def pubJwk = a2Jwk()
|
||||
def payloadBytes = Jwts.parserBuilder().verifyWith(pubJwk.toKey()).build().parse(compact).getPayload() as byte[]
|
||||
def payloadBytes = Jwts.parser().verifyWith(pubJwk.toKey()).build().parse(compact).getPayload() as byte[]
|
||||
def payload = new String(payloadBytes, StandardCharsets.UTF_8)
|
||||
assertEquals A4_JWS_PAYLOAD, payload
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ class RFC8037AppendixATest {
|
|||
assertEquals(rfcExpectedHeaderMap.get('epk'), jweHeaderMap.get('epk'))
|
||||
|
||||
//ensure that bob can decrypt:
|
||||
def jwt = Jwts.parserBuilder().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseClaimsJwe(jwe)
|
||||
def jwt = Jwts.parser().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseClaimsJwe(jwe)
|
||||
|
||||
assertEquals(issuer, jwt.getPayload().getIssuer())
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ class RFC8037AppendixATest {
|
|||
assertEquals(rfcExpectedHeaderMap.get('epk'), jweHeaderMap.get('epk'))
|
||||
|
||||
//ensure that Bob ("Dave") can decrypt:
|
||||
def jwt = Jwts.parserBuilder().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseClaimsJwe(jwe)
|
||||
def jwt = Jwts.parser().decryptWith(bobPrivJwk.toKey() as PrivateKey).build().parseClaimsJwe(jwe)
|
||||
|
||||
//assert that we've decrypted and the value in the body/content is as expected:
|
||||
assertEquals(issuer, jwt.getPayload().getIssuer())
|
||||
|
|
|
@ -38,7 +38,7 @@ class BasicTest {
|
|||
.signWith(key, SignatureAlgorithm.HS256)
|
||||
.compact()
|
||||
|
||||
JwtParser parser = Jwts.parserBuilder()
|
||||
JwtParser parser = Jwts.parser()
|
||||
.setSigningKey(key)
|
||||
.build()
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public class JavaReadmeTest {
|
|||
String jws = Jwts.builder().setContent(content, "text/plain").signWith(key, alg).compact();
|
||||
|
||||
// Parse the compact JWS:
|
||||
content = Jwts.parserBuilder().verifyWith(key).build().parseContentJws(jws).getPayload();
|
||||
content = Jwts.parser().verifyWith(key).build().parseContentJws(jws).getPayload();
|
||||
|
||||
assert message.equals(new String(content, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class JavaReadmeTest {
|
|||
.compact();
|
||||
|
||||
// Alice receives and verifies the compact JWS came from Bob:
|
||||
String subject = Jwts.parserBuilder()
|
||||
String subject = Jwts.parser()
|
||||
.verifyWith(pair.getPublic()) // <-- Bob's RSA public key
|
||||
.build().parseClaimsJws(jws).getPayload().getSubject();
|
||||
|
||||
|
@ -112,7 +112,7 @@ public class JavaReadmeTest {
|
|||
.compact();
|
||||
|
||||
// Alice receives and verifies the compact JWS came from Bob:
|
||||
String subject = Jwts.parserBuilder()
|
||||
String subject = Jwts.parser()
|
||||
.verifyWith(pair.getPublic()) // <-- Bob's EC public key
|
||||
.build().parseClaimsJws(jws).getPayload().getSubject();
|
||||
|
||||
|
@ -136,7 +136,7 @@ public class JavaReadmeTest {
|
|||
String jwe = Jwts.builder().setContent(content, "text/plain").encryptWith(key, enc).compact();
|
||||
|
||||
// Parse the compact JWE:
|
||||
content = Jwts.parserBuilder().decryptWith(key).build().parseContentJwe(jwe).getPayload();
|
||||
content = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe).getPayload();
|
||||
|
||||
assert message.equals(new String(content, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ public class JavaReadmeTest {
|
|||
.compact();
|
||||
|
||||
// Alice receives and decrypts the compact JWE:
|
||||
String audience = Jwts.parserBuilder()
|
||||
String audience = Jwts.parser()
|
||||
.decryptWith(pair.getPrivate()) // <-- Alice's RSA private key
|
||||
.build().parseClaimsJwe(jwe).getPayload().getAudience();
|
||||
|
||||
|
@ -183,7 +183,7 @@ public class JavaReadmeTest {
|
|||
String jwe = Jwts.builder().setIssuer("me").encryptWith(key, alg, enc).compact();
|
||||
|
||||
// Parse the compact JWE:
|
||||
String issuer = Jwts.parserBuilder().decryptWith(key).build()
|
||||
String issuer = Jwts.parser().decryptWith(key).build()
|
||||
.parseClaimsJwe(jwe).getPayload().getIssuer();
|
||||
|
||||
assert "me".equals(issuer);
|
||||
|
@ -208,7 +208,7 @@ public class JavaReadmeTest {
|
|||
.compact();
|
||||
|
||||
// Alice receives and decrypts the compact JWE:
|
||||
String audience = Jwts.parserBuilder()
|
||||
String audience = Jwts.parser()
|
||||
.decryptWith(pair.getPrivate()) // <-- Alice's EC private key
|
||||
.build().parseClaimsJwe(jwe).getPayload().getAudience();
|
||||
|
||||
|
@ -246,7 +246,7 @@ public class JavaReadmeTest {
|
|||
.compact();
|
||||
|
||||
// Parse the compact JWE:
|
||||
String issuer = Jwts.parserBuilder().decryptWith(password)
|
||||
String issuer = Jwts.parser().decryptWith(password)
|
||||
.build().parseClaimsJwe(jwe).getPayload().getIssuer();
|
||||
|
||||
assert "me".equals(issuer);
|
||||
|
|
Loading…
Reference in New Issue