added Claims mutation methods to JwtBuilder for convenience

This commit is contained in:
Les Hazlewood 2014-09-26 17:47:15 -07:00
parent 563aead2bd
commit 4f64231600
7 changed files with 615 additions and 53 deletions

View File

@ -38,7 +38,7 @@ import java.util.Map;
*
* @since 0.1
*/
public interface Claims extends Map<String, Object> {
public interface Claims extends Map<String, Object>, ClaimsMutator<Claims> {
/** JWT {@code Issuer} claims parameter name: <code>"iss"</code> */
public static final String ISSUER = "iss";
@ -70,12 +70,9 @@ public interface Claims extends Map<String, Object> {
String getIssuer();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.1">
* <code>iss</code></a> (issuer) value. A {@code null} value will remove the property from the JSON map.
*
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setIssuer(String iss);
/**
@ -87,12 +84,9 @@ public interface Claims extends Map<String, Object> {
String getSubject();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.2">
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the JSON map.
*
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setSubject(String sub);
/**
@ -104,12 +98,9 @@ public interface Claims extends Map<String, Object> {
String getAudience();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.3">
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the JSON map.
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setAudience(String aud);
/**
@ -123,14 +114,9 @@ public interface Claims extends Map<String, Object> {
Date getExpiration();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
* <code>exp</code></a> (expiration) timestamp. A {@code null} value will remove the property from the JSON map.
*
* <p>A JWT obtained after this timestamp should not be used.</p>
*
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setExpiration(Date exp);
/**
@ -144,14 +130,9 @@ public interface Claims extends Map<String, Object> {
Date getNotBefore();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.5">
* <code>nbf</code></a> (not before) timestamp. A {@code null} value will remove the property from the JSON map.
*
* <p>A JWT obtained before this timestamp should not be used.</p>
*
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setNotBefore(Date nbf);
/**
@ -165,14 +146,9 @@ public interface Claims extends Map<String, Object> {
Date getIssuedAt();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.6">
* <code>iat</code></a> (issued at) timestamp. A {@code null} value will remove the property from the JSON map.
*
* <p>The value is the timestamp when the JWT was created.</p>
*
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setIssuedAt(Date iat);
/**
@ -189,16 +165,9 @@ public interface Claims extends Map<String, Object> {
String getId();
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.7">
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the JSON map.
*
* <p>This value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a
* manner that ensures that there is a negligible probability that the same value will be accidentally
* assigned to a different data object. The ID can be used to prevent the JWT from being replayed.</p>
*
* @param jti the JWT {@code jti} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* {@inheritDoc}
*/
@Override //only for better/targeted JavaDoc
Claims setId(String jti);
}

View File

@ -0,0 +1,102 @@
/*
* 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 java.util.Date;
/**
* Mutation (modifications) to a {@link io.jsonwebtoken.Claims Claims} instance.
*
* @param <T> the type of mutator
* @see io.jsonwebtoken.JwtBuilder
* @see io.jsonwebtoken.Claims
* @since 0.2
*/
public interface ClaimsMutator<T extends ClaimsMutator> {
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.1">
* <code>iss</code></a> (issuer) value. A {@code null} value will remove the property from the JSON map.
*
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setIssuer(String iss);
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.2">
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the JSON map.
*
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setSubject(String sub);
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.3">
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the JSON map.
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setAudience(String aud);
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
* <code>exp</code></a> (expiration) timestamp. A {@code null} value will remove the property from the JSON map.
*
* <p>A JWT obtained after this timestamp should not be used.</p>
*
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setExpiration(Date exp);
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.5">
* <code>nbf</code></a> (not before) timestamp. A {@code null} value will remove the property from the JSON map.
*
* <p>A JWT obtained before this timestamp should not be used.</p>
*
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setNotBefore(Date nbf);
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.6">
* <code>iat</code></a> (issued at) timestamp. A {@code null} value will remove the property from the JSON map.
*
* <p>The value is the timestamp when the JWT was created.</p>
*
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setIssuedAt(Date iat);
/**
* Sets the JWT <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.7">
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the JSON map.
*
* <p>This value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a
* manner that ensures that there is a negligible probability that the same value will be accidentally
* assigned to a different data object. The ID can be used to prevent the JWT from being replayed.</p>
*
* @param jti the JWT {@code jti} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
*/
T setId(String jti);
}

View File

@ -16,6 +16,7 @@
package io.jsonwebtoken;
import java.security.Key;
import java.util.Date;
import java.util.Map;
/**
@ -23,7 +24,7 @@ import java.util.Map;
*
* @since 0.1
*/
public interface JwtBuilder {
public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
//replaces any existing header with the specified header.
@ -100,6 +101,223 @@ public interface JwtBuilder {
*/
JwtBuilder setClaims(Map<String, Object> claims);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.1">
* <code>iss</code></a> (issuer) value. A {@code null} value will remove the property from the Claims.
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setIssuer(String) issuer} field with the specified value. This allows you to write
* code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setIssuer("Joe").compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setIssuer("Joe");
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setIssuer(String iss);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.2">
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the Claims.
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setSubject(String) subject} field with the specified value. This allows you to write
* code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setSubject("Me").compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setSubject("Me");
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setSubject(String sub);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.3">
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the Claims.
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setAudience(String) audience} field with the specified value. This allows you to write
* code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setAudience("You").compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setSubject("You");
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setAudience(String aud);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
* <code>exp</code></a> (expiration) value. A {@code null} value will remove the property from the Claims.
*
* <p>A JWT obtained after this timestamp should not be used.</p>
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setExpiration(java.util.Date) expiration} field with the specified value. This allows
* you to write code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setExpiration(new Date(System.currentTimeMillis() + 3600000)).compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setExpiration(new Date(System.currentTimeMillis() + 3600000));
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setExpiration(Date exp);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.5">
* <code>nbf</code></a> (not before) value. A {@code null} value will remove the property from the Claims.
*
* <p>A JWT obtained before this timestamp should not be used.</p>
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setNotBefore(java.util.Date) notBefore} field with the specified value. This allows
* you to write code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setNotBefore(new Date()).compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setNotBefore(new Date());
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setNotBefore(Date nbf);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.6">
* <code>iat</code></a> (issued at) value. A {@code null} value will remove the property from the Claims.
*
* <p>The value is the timestamp when the JWT was created.</p>
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setIssuedAt(java.util.Date) issuedAt} field with the specified value. This allows
* you to write code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setIssuedAt(new Date()).compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setIssuedAt(new Date());
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setIssuedAt(Date iat);
/**
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.7">
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the Claims.
*
* <p>The value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a
* manner that ensures that there is a negligible probability that the same value will be accidentally
* assigned to a different data object. The ID can be used to prevent the JWT from being replayed.</p>
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set
* the Claims {@link Claims#setId(String) id} field with the specified value. This allows
* you to write code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().setId(UUID.randomUUID().toString()).compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().setIssuedAt(UUID.randomUUID().toString());
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param jti the JWT {@code jti} (id) value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
* @since 0.2
*/
@Override //only for better/targeted JavaDoc
JwtBuilder setId(String jti);
/**
* Sets a custom JWT Claims parameter value. A {@code null} value will remove the property from the Claims.
*
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set the
* named property on the Claims instance using the Claims {@link Claims#put(Object, Object) put} method. This allows
* you to write code like this:</p>
*
* <pre>
* String jwt = Jwts.builder().claim("aName", "aValue").compact();
* </pre>
*
* <p>instead of this:</p>
* <pre>
* Claims claims = Jwts.claims().put("aName", "aValue");
* String jwt = Jwts.builder().setClaims(claims).compact();
* </pre>
* <p>if desired.</p>
*
* @param name the JWT Claims property name
* @param value the value to set for the specified Claims property name
* @return the builder instance for method chaining.
* @since 0.2
*/
JwtBuilder claim(String name, Object value);
/**
* Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS.
*

View File

@ -29,9 +29,11 @@ import io.jsonwebtoken.impl.crypto.JwtSigner;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.lang.Objects;
import io.jsonwebtoken.lang.Strings;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;
import java.util.Map;
@SuppressWarnings("unchecked")
@ -117,6 +119,13 @@ public class DefaultJwtBuilder implements JwtBuilder {
return this;
}
protected Claims ensureClaims() {
if (this.claims == null) {
this.claims = new DefaultClaims();
}
return this.claims;
}
@Override
public JwtBuilder setClaims(Claims claims) {
this.claims = claims;
@ -129,13 +138,118 @@ public class DefaultJwtBuilder implements JwtBuilder {
return this;
}
@Override
public JwtBuilder setIssuer(String iss) {
if (Strings.hasText(iss)) {
ensureClaims().setIssuer(iss);
} else {
if (this.claims != null) {
claims.setIssuer(iss);
}
}
return this;
}
@Override
public JwtBuilder setSubject(String sub) {
if (Strings.hasText(sub)) {
ensureClaims().setSubject(sub);
} else {
if (this.claims != null) {
claims.setSubject(sub);
}
}
return this;
}
@Override
public JwtBuilder setAudience(String aud) {
if (Strings.hasText(aud)) {
ensureClaims().setAudience(aud);
} else {
if (this.claims != null) {
claims.setAudience(aud);
}
}
return this;
}
@Override
public JwtBuilder setExpiration(Date exp) {
if (exp != null) {
ensureClaims().setExpiration(exp);
} else {
if (this.claims != null) {
//noinspection ConstantConditions
this.claims.setExpiration(exp);
}
}
return this;
}
@Override
public JwtBuilder setNotBefore(Date nbf) {
if (nbf != null) {
ensureClaims().setNotBefore(nbf);
} else {
if (this.claims != null) {
//noinspection ConstantConditions
this.claims.setNotBefore(nbf);
}
}
return this;
}
@Override
public JwtBuilder setIssuedAt(Date iat) {
if (iat != null) {
ensureClaims().setIssuedAt(iat);
} else {
if (this.claims != null) {
//noinspection ConstantConditions
this.claims.setIssuedAt(iat);
}
}
return this;
}
@Override
public JwtBuilder setId(String jti) {
if (Strings.hasText(jti)) {
ensureClaims().setId(jti);
} else {
if (this.claims != null) {
claims.setId(jti);
}
}
return this;
}
@Override
public JwtBuilder claim(String name, Object value) {
Assert.hasText(name, "Claim property name cannot be null or empty.");
if (this.claims == null) {
if (value != null) {
ensureClaims().put(name, value);
}
} else {
if (value == null) {
this.claims.remove(name);
} else {
this.claims.put(name, value);
}
}
return this;
}
@Override
public String compact() {
if (payload == null && claims == null) {
if (payload == null && Collections.isEmpty(claims)) {
throw new IllegalStateException("Either 'payload' or 'claims' must be specified.");
}
if (payload != null && claims != null) {
if (payload != null && !Collections.isEmpty(claims)) {
throw new IllegalStateException("Both 'payload' and 'claims' cannot both be specified. Choose either one.");
}

View File

@ -47,11 +47,13 @@ public class JwtMap implements Map<String,Object> {
} else if (v instanceof Date) {
return (Date) v;
} else if (v instanceof Number) {
int seconds = ((Number) v).intValue();
return new Date(seconds * 1000);
long seconds = ((Number) v).longValue();
long millis = seconds * 1000;
return new Date(millis);
} else if (v instanceof String) {
int seconds = Integer.parseInt((String) v);
return new Date(seconds * 1000);
long seconds = Long.parseLong((String) v);
long millis = seconds * 1000;
return new Date(millis);
} else {
throw new IllegalStateException("Cannot convert '" + name + "' value [" + v + "] to Date instance.");
}

View File

@ -134,6 +134,128 @@ class JwtsTest {
}
}
@Test
void testConvenienceIssuer() {
String compact = Jwts.builder().setIssuer("Me").compact();
Claims claims = Jwts.parser().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.parser().parse(compact).body as Claims
assertNull claims.getIssuer()
}
@Test
void testConvenienceSubject() {
String compact = Jwts.builder().setSubject("Joe").compact();
Claims claims = Jwts.parser().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.parser().parse(compact).body as Claims
assertNull claims.getSubject()
}
@Test
void testConvenienceAudience() {
String compact = Jwts.builder().setAudience("You").compact();
Claims claims = Jwts.parser().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.parser().parse(compact).body as Claims
assertNull claims.getAudience()
}
private Date dateWithOnlySecondPrecision() {
return dateWithOnlySecondPrecision(System.currentTimeMillis());
}
private Date dateWithOnlySecondPrecision(long millis) {
long seconds = millis / 1000;
long secondOnlyPrecisionMillis = seconds * 1000;
return new Date(secondOnlyPrecisionMillis);
}
@Test
void testConvenienceExpiration() {
Date now = dateWithOnlySecondPrecision() //jwt exp only supports *seconds* since epoch:
String compact = Jwts.builder().setExpiration(now).compact();
Claims claims = Jwts.parser().parse(compact).body as Claims
def claimedDate = claims.getExpiration()
assertEquals claimedDate, now
compact = Jwts.builder().setIssuer("Me")
.setExpiration(now) //set it
.setExpiration(null) //null should remove it
.compact();
claims = Jwts.parser().parse(compact).body as Claims
assertNull claims.getExpiration()
}
@Test
void testConvenienceNotBefore() {
Date now = dateWithOnlySecondPrecision() //jwt exp only supports *seconds* since epoch:
String compact = Jwts.builder().setNotBefore(now).compact();
Claims claims = Jwts.parser().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.parser().parse(compact).body as Claims
assertNull claims.getNotBefore()
}
@Test
void testConvenienceIssuedAt() {
Date now = dateWithOnlySecondPrecision() //jwt exp only supports *seconds* since epoch:
String compact = Jwts.builder().setIssuedAt(now).compact();
Claims claims = Jwts.parser().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.parser().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.parser().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.parser().parse(compact).body as Claims
assertNull claims.getId()
}
@Test
void testHS256() {
testHmac(SignatureAlgorithm.HS256);

View File

@ -16,6 +16,7 @@
package io.jsonwebtoken
import org.testng.annotations.Test
import static org.testng.Assert.*
class SignatureAlgorithmTest {
@ -41,4 +42,38 @@ class SignatureAlgorithmTest {
void testUnrecognizedAlgorithmName() {
SignatureAlgorithm.forName('whatever')
}
@Test
void testIsHmac() {
for(SignatureAlgorithm alg : SignatureAlgorithm.values()) {
if (alg.name().startsWith("HS")) {
assertTrue alg.isHmac()
} else {
assertFalse alg.isHmac()
}
}
}
@Test
void testIsRsa() {
for(SignatureAlgorithm alg : SignatureAlgorithm.values()) {
if (alg.getDescription().startsWith("RSASSA")) {
assertTrue alg.isRsa()
} else {
assertFalse alg.isRsa()
}
}
}
@Test
void testIsEllipticCurve() {
for(SignatureAlgorithm alg : SignatureAlgorithm.values()) {
if (alg.name().startsWith("ES")) {
assertTrue alg.isEllipticCurve()
} else {
assertFalse alg.isEllipticCurve()
}
}
}
}