Filling out test cases

This commit is contained in:
Les Hazlewood 2014-09-26 21:55:30 -07:00
parent 6580c92211
commit 962e228428
6 changed files with 543 additions and 53 deletions

View File

@ -91,9 +91,6 @@ public class Jwts {
* @return a new {@link Claims} instance populated with the specified name/value pairs. * @return a new {@link Claims} instance populated with the specified name/value pairs.
*/ */
public static Claims claims(Map<String, Object> claims) { public static Claims claims(Map<String, Object> claims) {
if (claims == null) {
return claims();
}
return new DefaultClaims(claims); return new DefaultClaims(claims);
} }

View File

@ -27,6 +27,7 @@ import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator; import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator;
import io.jsonwebtoken.impl.crypto.JwtSignatureValidator; import io.jsonwebtoken.impl.crypto.JwtSignatureValidator;
import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Assert;
@ -239,9 +240,9 @@ public class DefaultJwtParser implements JwtParser {
} else { } else {
Object body = jwt.getBody(); Object body = jwt.getBody();
if (body instanceof Claims) { if (body instanceof Claims) {
return handler.onClaimsJwt((Jwt<Header,Claims>)jwt); return handler.onClaimsJwt((Jwt<Header, Claims>) jwt);
} else { } else {
return handler.onPlaintextJwt((Jwt<Header,String>)jwt); return handler.onPlaintextJwt((Jwt<Header, String>) jwt);
} }
} }
} }
@ -258,22 +259,30 @@ public class DefaultJwtParser implements JwtParser {
@Override @Override
public Jwt<Header, Claims> parseClaimsJwt(String claimsJwt) { public Jwt<Header, Claims> parseClaimsJwt(String claimsJwt) {
try {
return parse(claimsJwt, new JwtHandlerAdapter<Jwt<Header, Claims>>() { return parse(claimsJwt, new JwtHandlerAdapter<Jwt<Header, Claims>>() {
@Override @Override
public Jwt<Header, Claims> onClaimsJwt(Jwt<Header, Claims> jwt) { public Jwt<Header, Claims> onClaimsJwt(Jwt<Header, Claims> jwt) {
return jwt; return jwt;
} }
}); });
} catch (IllegalArgumentException iae) {
throw new UnsupportedJwtException("Signed JWSs are not supported.", iae);
}
} }
@Override @Override
public Jws<String> parsePlaintextJws(String plaintextJws) { public Jws<String> parsePlaintextJws(String plaintextJws) {
try {
return parse(plaintextJws, new JwtHandlerAdapter<Jws<String>>() { return parse(plaintextJws, new JwtHandlerAdapter<Jws<String>>() {
@Override @Override
public Jws<String> onPlaintextJws(Jws<String> jws) { public Jws<String> onPlaintextJws(Jws<String> jws) {
return jws; return jws;
} }
}); });
} catch (IllegalArgumentException iae) {
throw new UnsupportedJwtException("Signed JWSs are not supported.", iae);
}
} }
@Override @Override

View File

@ -1,34 +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.impl.crypto;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.lang.Assert;
import java.security.Key;
public abstract class AbstractSigner implements Signer {
protected final SignatureAlgorithm alg;
protected final Key key;
protected AbstractSigner(SignatureAlgorithm alg, Key key) {
Assert.notNull(alg, "SignatureAlgorithm cannot be null.");
Assert.notNull(key, "Key cannot be null.");
this.alg = alg;
this.key = key;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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 org.testng.annotations.Test
import static org.testng.Assert.*
class JwtHandlerAdapterTest {
@Test
void testOnPlaintextJwt() {
def handler = new JwtHandlerAdapter();
try {
handler.onPlaintextJwt(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned plaintext JWTs are not supported.'
}
}
@Test
void testOnClaimsJwt() {
def handler = new JwtHandlerAdapter();
try {
handler.onClaimsJwt(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned Claims JWTs are not supported.'
}
}
@Test
void testOnPlaintextJws() {
def handler = new JwtHandlerAdapter();
try {
handler.onPlaintextJws(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed plaintext JWSs are not supported.'
}
}
@Test
void testOnClaimsJws() {
def handler = new JwtHandlerAdapter();
try {
handler.onClaimsJws(null)
fail()
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed Claims JWSs are not supported.'
}
}
}

View File

@ -0,0 +1,410 @@
/*
* 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.TextCodec
import org.testng.annotations.Test
import javax.crypto.spec.SecretKeySpec
import java.security.SecureRandom
import static org.testng.Assert.*
class JwtParserTest {
private static final SecureRandom random = new SecureRandom(); //doesn't need to be seeded - just testing
protected static byte[] randomKey() {
//create random signing key for testing:
byte[] key = new byte[64];
random.nextBytes(key);
return key;
}
@Test
void testSetDuplicateSigningKeys() {
byte[] keyBytes = randomKey();
SecretKeySpec key = new SecretKeySpec(keyBytes, "HmacSHA256");
String compact = Jwts.builder().setPayload('Hello World!').signWith(SignatureAlgorithm.HS256, keyBytes).compact()
try {
Jwts.parser().setSigningKey(keyBytes).setSigningKey(key).parse(compact)
fail()
} catch (IllegalStateException ise) {
assertEquals ise.getMessage(), 'A key object and key bytes cannot both be specified. Choose either.'
}
}
@Test
void testIsSignedWithNullArgument() {
assertFalse Jwts.parser().isSigned(null)
}
@Test
void testIsSignedWithJunkArgument() {
assertFalse Jwts.parser().isSigned('hello');
}
@Test
void testParseWithJunkArgument() {
String junkPayload = '{;aklsjd;fkajsd;fkjasd;lfkj}'
String bad = TextCodec.BASE64.encode('{"alg":"none"}') + '.' +
TextCodec.BASE64.encode(junkPayload) + '.';
try {
Jwts.parser().parse(bad);
fail()
} catch (MalformedJwtException expected) {
assertEquals expected.getMessage(), 'Unable to read JSON value: ' + junkPayload
}
}
@Test
void testParseJwsWithBadAlgHeader() {
String badAlgorithmName = 'whatever'
String header = "{\"alg\":\"$badAlgorithmName\"}";
String payload = '{"subject":"Joe"}'
String badSig = ";aklsjdf;kajsd;fkjas;dklfj"
String bad = TextCodec.BASE64.encode(header) + '.' +
TextCodec.BASE64.encode(payload) + '.' +
TextCodec.BASE64.encode(badSig);
try {
Jwts.parser().setSigningKey(randomKey()).parse(bad);
fail()
} catch (SignatureException se) {
assertEquals se.getMessage(), "Unsupported signature algorithm '$badAlgorithmName'"
}
}
@Test
void testParseWithInvalidSignature() {
String header = '{"alg":"HS256"}'
String payload = '{"subject":"Joe"}'
String badSig = ";aklsjdf;kajsd;fkjas;dklfj"
String bad = TextCodec.BASE64.encode(header) + '.' +
TextCodec.BASE64.encode(payload) + '.' +
TextCodec.BASE64.encode(badSig);
try {
Jwts.parser().setSigningKey(randomKey()).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.'
}
}
@Test
void testParsePlaintextJwsWithIncorrectAlg() {
String header = '{"alg":"none"}'
String payload = '{"subject":"Joe"}'
String badSig = ";aklsjdf;kajsd;fkjas;dklfj"
String bad = TextCodec.BASE64.encode(header) + '.' +
TextCodec.BASE64.encode(payload) + '.' +
TextCodec.BASE64.encode(badSig);
try {
Jwts.parser().setSigningKey(randomKey()).parse(bad);
fail()
} catch (MalformedJwtException se) {
assertEquals se.getMessage(), 'JWT string has a digest/signature, but the header does not reference a valid signature algorithm.'
}
}
@Test
void testParseWithBase64EncodedSigningKey() {
byte[] key = randomKey();
String base64Encodedkey = TextCodec.BASE64.encode(key);
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, base64Encodedkey).compact()
assertTrue Jwts.parser().isSigned(compact)
Jwt<Header,String> jwt = Jwts.parser().setSigningKey(base64Encodedkey).parse(compact)
assertEquals jwt.body, payload
}
// ========================================================================
// parsePlaintextJwt tests
// ========================================================================
@Test
void testParsePlaintextJwt() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).compact()
Jwt<Header,String> jwt = Jwts.parser().parsePlaintextJwt(compact);
assertEquals jwt.getBody(), payload
}
@Test
void testParsePlaintextJwtWithClaimsJwt() {
String compact = Jwts.builder().setSubject('Joe').compact();
try {
Jwts.parser().parsePlaintextJwt(compact);
fail();
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned Claims JWTs are not supported.'
}
}
@Test
void testParsePlaintextJwtWithPlaintextJws() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, randomKey()).compact()
try {
Jwts.parser().parsePlaintextJws(compact);
fail();
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed JWSs are not supported.'
}
}
@Test
void testParsePlaintextJwtWithClaimsJws() {
String compact = Jwts.builder().setSubject('Joe').signWith(SignatureAlgorithm.HS256, randomKey()).compact()
try {
Jwts.parser().parsePlaintextJws(compact);
fail();
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed JWSs are not supported.'
}
}
// ========================================================================
// parseClaimsJwt tests
// ========================================================================
@Test
void testParseClaimsJwt() {
String subject = 'Joe'
String compact = Jwts.builder().setSubject(subject).compact()
Jwt<Header,Claims> jwt = Jwts.parser().parseClaimsJwt(compact);
assertEquals jwt.getBody().getSubject(), subject
}
@Test
void testParseClaimsJwtWithPlaintextJwt() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).compact()
try {
Jwts.parser().parseClaimsJwt(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned plaintext JWTs are not supported.'
}
}
@Test
void testParseClaimsJwtWithPlaintextJws() {
String payload = 'Hello world!'
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, randomKey()).compact()
try {
Jwts.parser().parseClaimsJwt(compact);
fail();
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed JWSs are not supported.'
}
}
@Test
void testParseClaimsJwtWithClaimsJws() {
String compact = Jwts.builder().setSubject('Joe').signWith(SignatureAlgorithm.HS256, randomKey()).compact()
try {
Jwts.parser().parseClaimsJwt(compact);
fail();
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed JWSs are not supported.'
}
}
// ========================================================================
// parsePlaintextJws tests
// ========================================================================
@Test
void testParsePlaintextJws() {
String payload = 'Hello world!'
byte[] key = randomKey()
String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, key).compact()
Jwt<Header,String> jwt = Jwts.parser().setSigningKey(key).parsePlaintextJws(compact);
assertEquals jwt.getBody(), payload
}
@Test
void testParsePlaintextJwsWithPlaintextJwt() {
String payload = 'Hello world!'
byte[] key = randomKey()
String compact = Jwts.builder().setPayload(payload).compact()
try {
Jwts.parser().setSigningKey(key).parsePlaintextJws(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned plaintext JWTs are not supported.'
}
}
@Test
void testParsePlaintextJwsWithClaimsJwt() {
String subject = 'Joe'
byte[] key = randomKey()
String compact = Jwts.builder().setSubject(subject).compact()
try {
Jwts.parser().setSigningKey(key).parsePlaintextJws(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned Claims JWTs are not supported.'
}
}
@Test
void testParsePlaintextJwsWithClaimsJws() {
String subject = 'Joe'
byte[] key = randomKey()
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).parsePlaintextJws(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed Claims JWSs are not supported.'
}
}
// ========================================================================
// parseClaimsJws tests
// ========================================================================
@Test
void testParseClaimsJws() {
String sub = 'Joe'
byte[] key = randomKey()
String compact = Jwts.builder().setSubject(sub).signWith(SignatureAlgorithm.HS256, key).compact()
Jwt<Header,Claims> jwt = Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
assertEquals jwt.getBody().getSubject(), sub
}
@Test
void testParseClaimsJwsWithPlaintextJwt() {
String payload = 'Hello world!'
byte[] key = randomKey()
String compact = Jwts.builder().setPayload(payload).compact()
try {
Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned plaintext JWTs are not supported.'
}
}
@Test
void testParseClaimsJwsWithClaimsJwt() {
String subject = 'Joe'
byte[] key = randomKey()
String compact = Jwts.builder().setSubject(subject).compact()
try {
Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Unsigned Claims JWTs are not supported.'
}
}
@Test
void testParseClaimsJwsWithPlaintextJws() {
String subject = 'Joe'
byte[] key = randomKey()
String compact = Jwts.builder().setSubject(subject).signWith(SignatureAlgorithm.HS256, key).compact()
try {
Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
} catch (UnsupportedJwtException e) {
assertEquals e.getMessage(), 'Signed Claims JWSs are not supported.'
}
}
}

View File

@ -15,6 +15,8 @@
*/ */
package io.jsonwebtoken package io.jsonwebtoken
import io.jsonwebtoken.impl.DefaultHeader
import io.jsonwebtoken.impl.DefaultJwsHeader
import org.testng.annotations.Test import org.testng.annotations.Test
import java.security.KeyPair import java.security.KeyPair
@ -27,6 +29,45 @@ import static org.testng.Assert.*
class JwtsTest { class JwtsTest {
@Test
void testHeaderWithNoArgs() {
def header = Jwts.header()
assertTrue header instanceof DefaultHeader
}
@Test
void testHeaderWithMapArg() {
def header = Jwts.header([alg: "HS256"])
assertTrue header instanceof DefaultHeader
assertEquals header.alg, 'HS256'
}
@Test
void testJwsHeaderWithNoArgs() {
def header = Jwts.jwsHeader()
assertTrue header instanceof DefaultJwsHeader
}
@Test
void testJwsHeaderWithMapArg() {
def header = Jwts.jwsHeader([alg: "HS256"])
assertTrue header instanceof DefaultJwsHeader
assertEquals header.getAlgorithm(), 'HS256'
}
@Test
void testClaims() {
Claims claims = Jwts.claims()
assertNotNull claims
}
@Test
void testClaimsWithMapArg() {
Claims claims = Jwts.claims([sub: 'Joe'])
assertNotNull claims
assertEquals claims.getSubject(), 'Joe'
}
@Test @Test
void testPlaintextJwtString() { void testPlaintextJwtString() {
@ -179,11 +220,11 @@ class JwtsTest {
assertNull claims.getAudience() assertNull claims.getAudience()
} }
private Date dateWithOnlySecondPrecision() { private static Date dateWithOnlySecondPrecision() {
return dateWithOnlySecondPrecision(System.currentTimeMillis()); return dateWithOnlySecondPrecision(System.currentTimeMillis());
} }
private Date dateWithOnlySecondPrecision(long millis) { private static Date dateWithOnlySecondPrecision(long millis) {
long seconds = millis / 1000; long seconds = millis / 1000;
long secondOnlyPrecisionMillis = seconds * 1000; long secondOnlyPrecisionMillis = seconds * 1000;
return new Date(secondOnlyPrecisionMillis); return new Date(secondOnlyPrecisionMillis);