org.elastos.did.jwt.Claims Maven / Gradle / Ivy
Show all versions of didsdk Show documentation
/*
* Copyright (c) 2019 Elastos Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.elastos.did.jwt;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.elastos.did.exception.UnknownInternalException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* A JWT Claims set.
*
*
* This is ultimately a map and any values can be added to it, but JWT
* standard names are provided as type-safe getters and setters for convenience.
*
*
*
* Because this interface extends {@code Map<String, Object>},
* if you would like to add your own properties, you simply use map methods,
* for example:
*
*
*
* claims.{@link Map#put(Object, Object) put}("someKey", "someValue");
*
*
* Creation
*
*
* It is easiest to create a {@code Claims} instance by calling one of the
* {@link JwtBuilder#createClaims() JwtBuilder.createClaims()} factory methods.
*
*/
public class Claims implements Map {
/** JWT {@code Issuer} claims parameter name: "iss"
*/
public static final String ISSUER = "iss";
/** JWT {@code Subject} claims parameter name: "sub"
*/
public static final String SUBJECT = "sub";
/** JWT {@code Audience} claims parameter name: "aud"
*/
public static final String AUDIENCE = "aud";
/** JWT {@code Expiration} claims parameter name: "exp"
*/
public static final String EXPIRATION = "exp";
/** JWT {@code Not Before} claims parameter name: "nbf"
*/
public static final String NOT_BEFORE = "nbf";
/** JWT {@code Issued At} claims parameter name: "iat"
*/
public static final String ISSUED_AT = "iat";
/** JWT {@code JWT ID} claims parameter name: "jti"
*/
public static final String ID = "jti";
private io.jsonwebtoken.Claims impl;
/**
* Construct a Claims instance form an internal implementation object.
*
* @param impl An io.jsonwebtoken.Claims object
*/
protected Claims(io.jsonwebtoken.Claims impl) {
this.impl = impl;
}
/**
* Get the internal implementation object.
*
* @return the io.jsonwebtoken.Claims object
*/
protected io.jsonwebtoken.Claims getImpl() {
return impl;
}
/**
* Returns the JWT
* iss
(issuer) value or {@code null} if not present.
*
* @return the JWT {@code iss} value or {@code null} if not present
*/
public String getIssuer() {
return impl.getIssuer();
}
/**
* Sets the JWT
* iss
(issuer) value. A {@code null} value will remove the
* property from the Claims.
*
* @param iss the JWT {@code iss} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining
*/
public Claims setIssuer(String iss) {
impl.setIssuer(iss);
return this;
}
/**
* Returns the JWT
* sub
(subject) value or {@code null} if not present.
*
* @return the JWT {@code sub} value or {@code null} if not present
*/
public String getSubject() {
return impl.getSubject();
}
/**
* Sets the JWT
* sub
(subject) value. A {@code null} value will remove
* the property from the Claims.
*
* @param sub the JWT {@code sub} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining
*/
public Claims setSubject(String sub) {
impl.setSubject(sub);
return this;
}
/**
* Returns the JWT
* aud
(audience) value or {@code null} if not present.
*
* @return the JWT {@code aud} value or {@code null} if not present
*/
public String getAudience() {
return impl.getAudience();
}
/**
* Sets the JWT
* aud
(audience) value. A {@code null} value will remove
* the property from the Claims.
*
* @param aud the JWT {@code aud} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining
*/
public Claims setAudience(String aud) {
impl.setAudience(aud);
return this;
}
/**
* Returns the JWT
* exp
(expiration) timestamp or {@code null} if not
* present.
*
*
* A JWT obtained after this timestamp should not be used.
*
*
* @return the JWT {@code exp} value or {@code null} if not present
*/
public Date getExpiration() {
return impl.getExpiration();
}
/**
* Sets the JWT
* exp
(expiration) timestamp. A {@code null} value will
* remove the property from the Claims.
*
*
* A JWT obtained after this timestamp should not be used.
*
*
* @param exp the JWT {@code exp} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining
*/
public Claims setExpiration(Date exp) {
impl.setExpiration(exp);
return this;
}
/**
* Returns the JWT
* nbf
(not before) timestamp or {@code null} if not
* present.
*
*
* A JWT obtained before this timestamp should not be used.
*
*
* @return the JWT {@code nbf} value or {@code null} if not present
*/
public Date getNotBefore() {
return impl.getNotBefore();
}
/**
* Sets the JWT
* nbf
(not before) timestamp. A {@code null} value will
* remove the property from the Claims.
*
*
* A JWT obtained before this timestamp should not be used.
*
*
* @param nbf the JWT {@code nbf} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining
*/
public Claims setNotBefore(Date nbf) {
impl.setNotBefore(nbf);
return this;
}
/**
* Returns the JWT
* iat
(issued at) timestamp or {@code null} if not
* present.
*
*
* If present, this value is the timestamp when the JWT was created.
*
*
* @return the JWT {@code nbf} value or {@code null} if not present
*/
public Date getIssuedAt() {
return impl.getIssuedAt();
}
/**
* Sets the JWT
* iat
(issued at) timestamp. A {@code null} value will
* remove the property from the Claims.
*
*
* The value is the timestamp when the JWT was created.
*
*
* @param iat the JWT {@code iat} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining.
*/
public Claims setIssuedAt(Date iat) {
impl.setIssuedAt(iat);
return this;
}
/**
* Returns the JWTs
* jti
(JWT ID) value or {@code null} if not present.
*
*
* This value is a CaSe-SenSiTiVe unique identifier for the JWT. If
* available, this value is expected to 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.
*
*
* @return the JWT {@code jti} value or {@code null} if not present
*/
public String getId() {
return impl.getId();
}
/**
* Sets the JWT
* jti
(JWT ID) value. A {@code null} value will remove the
* property from the Claims.
*
*
* 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.
*
*
* @param jti the JWT {@code jti} value or {@code null} to remove the
* property from the Claims
* @return the {@code Claims} instance for method chaining
*/
public Claims setId(String jti) {
impl.setId(jti);
return this;
}
/**
* Returns the JWTs claim ({@code claimName}) value as a type
* {@code requiredType}, or {@code null} if not present.
*
*
* SDK only converts simple String, Date, Long, Integer, Short and
* Byte types automatically.
*
*
* @param claimName name of claim
* @param requiredType the type of the value expected to be returned
* @param the type of the value expected to be returned
* @return the JWT {@code claimName} value or {@code null} if not present
*/
public T get(String claimName, Class requiredType) {
checkArgument(claimName != null && !claimName.isEmpty(), "Invalid key");
return impl.get(claimName, requiredType);
}
/**
* Returns the number of claimName-claimValue mappings in this Claims.
*
* @return the number of claimName-claimValue mappings in this Claims
*/
@Override
public int size() {
return impl.size();
}
/**
* Returns true if this Claims contains no claimName-claimValue mappings.
*
* @return true if this Claims contains no claimName-claimValue mappings
*/
@Override
public boolean isEmpty() {
return impl.isEmpty();
}
/**
* Returns {@code true} if this Claims contains a mapping for the specified
* key. More formally, returns {@code true} if and only if
* this Claims contains a mapping for a key {@code k} such that
* {@code Objects.equals(key, k)}. (There can be
* at most one such mapping.)
*
* @param key key whose presence in this Claims is to be tested
* @return {@code true} if this Claims contains a mapping for the specified
* key
*/
@Override
public boolean containsKey(Object key) {
checkArgument(key != null, "Invalid key");
return impl.containsKey(key);
}
/**
* Returns {@code true} if this Claims maps one or more keys to the
* specified value. More formally, returns {@code true} if and only if
* this Claims contains at least one mapping to a value {@code v} such that
* {@code Objects.equals(value, v)}. This operation
* will probably require time linear in the Claims size for most
* implementations of the {@code Map} interface.
*
* @param value value whose presence in this Claims is to be tested
* @return {@code true} if this Claims maps one or more keys to the
* specified value
*/
@Override
public boolean containsValue(Object value) {
return impl.containsValue(value);
}
/**
* Returns the value to which the specified key is mapped,
* or {@code null} if this Claims contains no mapping for the key.
*
* More formally, if this Claims contains a mapping from a key
* {@code k} to a value {@code v} such that
* {@code Objects.equals(key, k)},
* then this method returns {@code v}; otherwise
* it returns {@code null}. (There can be at most one such mapping.)
*
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped, or
* {@code null} if this Claims contains no mapping for the key
*/
@Override
public Object get(Object key) {
checkArgument(key != null, "Invalid key");
return impl.get(key);
}
/**
* Returns the JSON string value to which the specified key is mapped,
* or {@code null} if this Claims contains no mapping for the key.
*
*
More formally, if this Claims contains a mapping from a key
* {@code k} to a value {@code v} such that
* {@code Objects.equals(key, k)},
* then this method returns {@code v}; otherwise
* it returns {@code null}. (There can be at most one such mapping.)
*
* @param key the key whose associated value is to be returned
* @return the JSON string to which the specified key is mapped
*/
public String getAsJson(Object key) {
checkArgument(key != null, "Invalid key");
Object v = impl.get(key);
if (v == null)
return null;
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(v);
} catch (JsonProcessingException e) {
throw new UnknownInternalException(e);
}
}
/**
* Associates the specified value with the specified key in this Claims
* (optional operation). If the Claims previously contained a mapping for
* the key, the old value is replaced by the specified value. (A Claims
* {@code m} is said to contain a mapping for a key {@code k} if and only
* if {@link #containsKey(Object) m.containsKey(k)} would return
* {@code true}.)
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
* (A {@code null} return can also indicate that the Claims
* previously associated {@code null} with {@code key},
* if the implementation supports {@code null} values.)
*/
@Override
public Object put(String key, Object value) {
checkArgument(key != null && !key.isEmpty(), "Invalid key");
return impl.put(key, value);
}
/**
* Associates the specified value with the specified key in this Claims
* (optional operation).
*
* @param key the key string
* @param json the json string
* @return the previous value associated with key, or null if there was
* no mapping for key. (A null return can also indicate that
* the Claims previously associated null with key, if the
* implementation supports null values.)
*/
public Object putWithJson(String key, String json) {
checkArgument(key != null && !key.isEmpty(), "Invalid key");
checkArgument(json != null && !json.isEmpty(), "Invalid json");
return impl.put(key, json2Map(json));
}
/**
* Removes the claimName from this Claims if it is present
* (optional operation). More formally, if this Claims contains a mapping
* from key {@code k} to value {@code v} such that
* {@code Objects.equals(key, k)}, that mapping
* is removed.
*
*
Returns the value to which this Claims previously associated the key,
* or {@code null} if the Claims contained no mapping for the key.
*
*
The Claims will not contain a mapping for the specified key once the
* call returns.
*
* @param key the claimName to be removed from the Claims
* @return the previous value associated with {@code key}, or
* {@code null} if there was no clainName for {@code key}.
*/
@Override
public Object remove(Object key) {
checkArgument(key != null, "Invalid key");
return impl.remove(key);
}
/**
* Copies all of the mappings from the specified map to this Claims
* (optional operation). The effect of this call is equivalent to that
* of calling {@link #put(Object,Object) put(k, v)} on this Claims once
* for each mapping from key {@code k} to value {@code v} in the
* specified map. The behavior of this operation is undefined if the
* specified map is modified while the operation is in progress.
*
* @param map claims to be stored in this Claims
*/
@Override
public void putAll(Map extends String, ? extends Object> map) {
checkArgument(map != null, "Invalid map");
impl.putAll(map);
}
/**
* Deserialize the JSON string to map, then copies all of the mappings
* from the map to this Claims.
*
* @param json the JSON claims
*/
public void putAllWithJson(String json) {
checkArgument(json != null && !json.isEmpty(), "Invalid json");
impl.putAll(json2Map(json));
}
/**
* Removes all of the claimed entries from this Claims (optional operation).
* The Claims will be empty after this call returns.
*/
@Override
public void clear() {
impl.clear();
}
/**
* Returns a {@link Set} view of the claimNames contained in this Claims.
* The set is backed by the Claims, so changes to the Claims are
* reflected in the set, and vice-versa. If the Claims is modified
* while an iteration over the set is in progress (except through
* the iterator's own {@code remove} operation), the results of
* the iteration are undefined. The set supports element removal,
* which removes the corresponding mapping from the Claims, via the
* {@code Iterator.remove}, {@code Set.remove},
* {@code removeAll}, {@code retainAll}, and {@code clear}
* operations. It does not support the {@code add} or {@code addAll}
* operations.
*
* @return a set view of the keys contained in this Claims
*/
@Override
public Set keySet() {
return impl.keySet();
}
/**
* Returns a {@link Collection} view of the claimed values contained
* in this Claims.
*
* The collection is backed by the Claims, so changes to the Claims are
* reflected in the collection, and vice-versa. If the Claims is
* modified while an iteration over the collection is in progress
* (except through the iterator's own {@code remove} operation),
* the results of the iteration are undefined. The collection
* supports element removal, which removes the corresponding
* mapping from the Claims, via the {@code Iterator.remove},
* {@code Collection.remove}, {@code removeAll},
* {@code retainAll} and {@code clear} operations. It does not
* support the {@code add} or {@code addAll} operations.
*
* @return a collection view of the claimed values contained in this Claims
*/
@Override
public Collection