All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nimbusds.jwt.JWTClaimsSet Maven / Gradle / Ivy

package com.nimbusds.jwt;


import java.text.ParseException;
import java.util.*;

import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;

import com.nimbusds.jose.util.JSONObjectUtils;


/**
 * JSON Web Token (JWT) claims set.
 *
 * 

Supports all {@link #getRegisteredNames()} registered claims} of the JWT * specification: * *

    *
  • iss - Issuer *
  • sub - Subject *
  • aud - Audience *
  • exp - Expiration Time *
  • nbf - Not Before *
  • iat - Issued At *
  • jti - JWT ID *
  • typ - Type *
* *

The set may also contain {@link #setCustomClaims custom claims}; these * will be serialised and parsed along the registered ones. * * @author Vladimir Dzhuvinov * @author Justin Richer * @version $version$ (2014-08-16) */ public class JWTClaimsSet implements ReadOnlyJWTClaimsSet { private static final String TYPE_CLAIM = "typ"; private static final String JWT_ID_CLAIM = "jti"; private static final String ISSUED_AT_CLAIM = "iat"; private static final String NOT_BEFORE_CLAIM = "nbf"; private static final String EXPIRATION_TIME_CLAIM = "exp"; private static final String AUDIENCE_CLAIM = "aud"; private static final String SUBJECT_CLAIM = "sub"; private static final String ISSUER_CLAIM = "iss"; /** * The registered claim names. */ private static final Set REGISTERED_CLAIM_NAMES; /** * Initialises the registered claim name set. */ static { Set n = new HashSet<>(); n.add(ISSUER_CLAIM); n.add(SUBJECT_CLAIM); n.add(AUDIENCE_CLAIM); n.add(EXPIRATION_TIME_CLAIM); n.add(NOT_BEFORE_CLAIM); n.add(ISSUED_AT_CLAIM); n.add(JWT_ID_CLAIM); n.add(TYPE_CLAIM); REGISTERED_CLAIM_NAMES = Collections.unmodifiableSet(n); } /** * The issuer claim. */ private String iss = null; /** * The subject claim. */ private String sub = null; /** * The audience claim. */ private List aud = null; /** * The expiration time claim. */ private Date exp = null; /** * The not-before claim. */ private Date nbf = null; /** * The issued-at claim. */ private Date iat = null; /** * The JWT ID claim. */ private String jti = null; /** * The type claim. */ private String typ = null; /** * Custom claims. */ private Map customClaims = new HashMap<>(); /** * Creates a new empty JWT claims set. */ public JWTClaimsSet() { // Nothing to do } /** * Creates a copy of the specified JWT claims set. * * @param old The JWT claims set to copy. Must not be {@code null}. */ public JWTClaimsSet(final ReadOnlyJWTClaimsSet old) { super(); setAllClaims(old.getAllClaims()); } /** * Gets the registered JWT claim names. * * @return The registered claim names, as a unmodifiable set. */ public static Set getRegisteredNames() { return REGISTERED_CLAIM_NAMES; } @Override public String getIssuer() { return iss; } /** * Sets the issuer ({@code iss}) claim. * * @param iss The issuer claim, {@code null} if not specified. */ public void setIssuer(final String iss) { this.iss = iss; } @Override public String getSubject() { return sub; } /** * Sets the subject ({@code sub}) claim. * * @param sub The subject claim, {@code null} if not specified. */ public void setSubject(final String sub) { this.sub = sub; } @Override public List getAudience() { return aud; } /** * Sets the audience ({@code aud}) claim. * * @param aud The audience claim, {@code null} if not specified. */ public void setAudience(final List aud) { this.aud = aud; } /** * Sets a single-valued audience ({@code aud}) claim. * * @param aud The audience claim, {@code null} if not specified. */ public void setAudience(final String aud) { if (aud == null) { this.aud = null; } else { this.aud = Arrays.asList(aud); } } @Override public Date getExpirationTime() { return exp; } /** * Sets the expiration time ({@code exp}) claim. * * @param exp The expiration time, {@code null} if not specified. */ public void setExpirationTime(final Date exp) { this.exp = exp; } @Override public Date getNotBeforeTime() { return nbf; } /** * Sets the not-before ({@code nbf}) claim. * * @param nbf The not-before claim, {@code null} if not specified. */ public void setNotBeforeTime(final Date nbf) { this.nbf = nbf; } @Override public Date getIssueTime() { return iat; } /** * Sets the issued-at ({@code iat}) claim. * * @param iat The issued-at claim, {@code null} if not specified. */ public void setIssueTime(final Date iat) { this.iat = iat; } @Override public String getJWTID() { return jti; } /** * Sets the JWT ID ({@code jti}) claim. * * @param jti The JWT ID claim, {@code null} if not specified. */ public void setJWTID(final String jti) { this.jti = jti; } @Override public String getType() { return typ; } /** * Sets the type ({@code typ}) claim. * * @param typ The type claim, {@code null} if not specified. */ public void setType(final String typ) { this.typ = typ; } @Override public Object getCustomClaim(final String name) { return customClaims.get(name); } /** * Sets a custom (non-registered) claim. * * @param name The name of the custom claim. Must not be {@code null}. * @param value The value of the custom claim, should map to a valid * JSON entity, {@code null} if not specified. * * @throws IllegalArgumentException If the specified custom claim name * matches a registered claim name. */ public void setCustomClaim(final String name, final Object value) { if (getRegisteredNames().contains(name)) { throw new IllegalArgumentException("The claim name \"" + name + "\" matches a registered name"); } customClaims.put(name, value); } @Override public Map getCustomClaims() { return Collections.unmodifiableMap(customClaims); } /** * Sets the custom (non-registered) claims. If a claim value doesn't * map to a JSON entity it will be ignored during serialisation. * * @param customClaims The custom claims, empty map or {@code null} if * none. */ public void setCustomClaims(final Map customClaims) { if (customClaims == null) { this.customClaims.clear(); } else { this.customClaims = customClaims; } } @Override public Object getClaim(final String name) { if(ISSUER_CLAIM.equals(name)) { return getIssuer(); } else if(SUBJECT_CLAIM.equals(name)) { return getSubject(); } else if(AUDIENCE_CLAIM.equals(name)) { return getAudience(); } else if(EXPIRATION_TIME_CLAIM.equals(name)) { return getExpirationTime(); } else if(NOT_BEFORE_CLAIM.equals(name)) { return getNotBeforeTime(); } else if(ISSUED_AT_CLAIM.equals(name)) { return getIssueTime(); } else if(JWT_ID_CLAIM.equals(name)) { return getJWTID(); } else if(TYPE_CLAIM.equals(name)) { return getType(); } else { return getCustomClaim(name); } } @Override public String getStringClaim(final String name) throws ParseException { Object value = getClaim(name); if (value == null || value instanceof String) { return (String)value; } else { throw new ParseException("The \"" + name + "\" claim is not a String", 0); } } @Override public Boolean getBooleanClaim(final String name) throws ParseException { Object value = getClaim(name); if (value == null || value instanceof Boolean) { return (Boolean)value; } else { throw new ParseException("The \"" + name + "\" claim is not a Boolean", 0); } } @Override public Integer getIntegerClaim(final String name) throws ParseException { Object value = getClaim(name); if (value == null) { return null; } else if (value instanceof Number) { return ((Number)value).intValue(); } else { throw new ParseException("The \"" + name + "\" claim is not an Integer", 0); } } @Override public Long getLongClaim(final String name) throws ParseException { Object value = getClaim(name); if (value == null) { return null; } else if (value instanceof Number) { return ((Number)value).longValue(); } else { throw new ParseException("The \"" + name + "\" claim is not a Number", 0); } } @Override public Float getFloatClaim(final String name) throws ParseException { Object value = getClaim(name); if (value == null) { return null; } else if (value instanceof Number) { return ((Number)value).floatValue(); } else { throw new ParseException("The \"" + name + "\" claim is not a Float", 0); } } @Override public Double getDoubleClaim(final String name) throws ParseException { Object value = getClaim(name); if (value == null) { return null; } else if (value instanceof Number) { return ((Number)value).doubleValue(); } else { throw new ParseException("The \"" + name + "\" claim is not a Double", 0); } } /** * Sets the specified claim, whether registered or custom. * * @param name The name of the claim to set. Must not be {@code null}. * @param value The value of the claim to set, {@code null} if not * specified. * * @throws IllegalArgumentException If the claim is registered and its * value is not of the expected type. */ public void setClaim(final String name, final Object value) { if (ISSUER_CLAIM.equals(name)) { if (value == null || value instanceof String) { setIssuer((String) value); } else { throw new IllegalArgumentException("Issuer claim must be a String"); } } else if (SUBJECT_CLAIM.equals(name)) { if (value == null || value instanceof String) { setSubject((String) value); } else { throw new IllegalArgumentException("Subject claim must be a String"); } } else if (AUDIENCE_CLAIM.equals(name)) { if (value == null || value instanceof List) { setAudience((List) value); } else { throw new IllegalArgumentException("Audience claim must be a List"); } } else if (EXPIRATION_TIME_CLAIM.equals(name)) { if (value == null || value instanceof Date) { setExpirationTime((Date) value); } else { throw new IllegalArgumentException("Expiration claim must be a Date"); } } else if (NOT_BEFORE_CLAIM.equals(name)) { if (value == null || value instanceof Date) { setNotBeforeTime((Date) value); } else { throw new IllegalArgumentException("Not-before claim must be a Date"); } } else if (ISSUED_AT_CLAIM.equals(name)) { if (value == null || value instanceof Date) { setIssueTime((Date) value); } else { throw new IllegalArgumentException("Issued-at claim must be a Date"); } } else if (JWT_ID_CLAIM.equals(name)) { if (value == null || value instanceof String) { setJWTID((String) value); } else { throw new IllegalArgumentException("JWT-ID claim must be a String"); } } else if (TYPE_CLAIM.equals(name)) { if (value == null || value instanceof String) { setType((String) value); } else { throw new IllegalArgumentException("Type claim must be a String"); } } else { setCustomClaim(name, value); } } @Override public Map getAllClaims() { Map allClaims = new HashMap<>(); allClaims.putAll(customClaims); for (String registeredClaim : REGISTERED_CLAIM_NAMES) { Object value = getClaim(registeredClaim); if (value != null) { allClaims.put(registeredClaim, value); } } return Collections.unmodifiableMap(allClaims); } /** * Sets the claims of this JWT claims set, replacing any existing ones. * * @param newClaims The JWT claims. Must not be {@code null}. */ public void setAllClaims(final Map newClaims) { for (String name : newClaims.keySet()) { setClaim(name, newClaims.get(name)); } } @Override public JSONObject toJSONObject() { JSONObject o = new JSONObject(customClaims); if (iss != null) { o.put(ISSUER_CLAIM, iss); } if (sub != null) { o.put(SUBJECT_CLAIM, sub); } if (aud != null && ! aud.isEmpty()) { if (aud.size() == 1) { o.put(AUDIENCE_CLAIM, aud.get(0)); } else { JSONArray audArray = new JSONArray(); audArray.addAll(aud); o.put(AUDIENCE_CLAIM, audArray); } } if (exp != null) { o.put(EXPIRATION_TIME_CLAIM, exp.getTime() / 1000); } if (nbf != null) { o.put(NOT_BEFORE_CLAIM, nbf.getTime() / 1000); } if (iat != null) { o.put(ISSUED_AT_CLAIM, iat.getTime() / 1000); } if (jti != null) { o.put(JWT_ID_CLAIM, jti); } if (typ != null) { o.put(TYPE_CLAIM, typ); } return o; } /** * Parses a JSON Web Token (JWT) claims set from the specified JSON * object representation. * * @param json The JSON object to parse. Must not be {@code null}. * * @return The JWT claims set. * * @throws ParseException If the specified JSON object doesn't * represent a valid JWT claims set. */ public static JWTClaimsSet parse(final JSONObject json) throws ParseException { JWTClaimsSet cs = new JWTClaimsSet(); // Parse registered + custom params for (final String name: json.keySet()) { if (name.equals(ISSUER_CLAIM)) { cs.setIssuer(JSONObjectUtils.getString(json, ISSUER_CLAIM)); } else if (name.equals(SUBJECT_CLAIM)) { cs.setSubject(JSONObjectUtils.getString(json, SUBJECT_CLAIM)); } else if (name.equals(AUDIENCE_CLAIM)) { Object audValue = json.get(AUDIENCE_CLAIM); if (audValue instanceof String) { List singleAud = new ArrayList<>(); singleAud.add(JSONObjectUtils.getString(json, AUDIENCE_CLAIM)); cs.setAudience(singleAud); } else if (audValue instanceof List) { cs.setAudience(JSONObjectUtils.getStringList(json, AUDIENCE_CLAIM)); } } else if (name.equals(EXPIRATION_TIME_CLAIM)) { cs.setExpirationTime(new Date(JSONObjectUtils.getLong(json, EXPIRATION_TIME_CLAIM) * 1000)); } else if (name.equals(NOT_BEFORE_CLAIM)) { cs.setNotBeforeTime(new Date(JSONObjectUtils.getLong(json, NOT_BEFORE_CLAIM) * 1000)); } else if (name.equals(ISSUED_AT_CLAIM)) { cs.setIssueTime(new Date(JSONObjectUtils.getLong(json, ISSUED_AT_CLAIM) * 1000)); } else if (name.equals(JWT_ID_CLAIM)) { cs.setJWTID(JSONObjectUtils.getString(json, JWT_ID_CLAIM)); } else if (name.equals(TYPE_CLAIM)) { cs.setType(JSONObjectUtils.getString(json, TYPE_CLAIM)); } else { cs.setCustomClaim(name, json.get(name)); } } return cs; } /** * Parses a JSON Web Token (JWT) claims set from the specified JSON * object string representation. * * @param s The JSON object string to parse. Must not be {@code null}. * * @return The JWT claims set. * * @throws ParseException If the specified JSON object string doesn't * represent a valid JWT claims set. */ public static JWTClaimsSet parse(final String s) throws ParseException { return parse(JSONObjectUtils.parseJSONObject(s)); } @Override public String toString() { return "JWTClaimsSet [iss=" + iss + ", sub=" + sub + ", aud=" + aud + ", exp=" + exp + ", nbf=" + nbf + ", iat=" + iat + ", jti=" + jti + ", typ=" + typ + ", customClaims=" + customClaims + "]"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy