001package com.nimbusds.jwt; 002 003 004import java.text.ParseException; 005 006import net.minidev.json.JSONObject; 007 008import com.nimbusds.jose.Algorithm; 009import com.nimbusds.jose.Header; 010import com.nimbusds.jose.JWEAlgorithm; 011import com.nimbusds.jose.JWSAlgorithm; 012import com.nimbusds.jose.util.Base64URL; 013import com.nimbusds.jose.util.JSONObjectUtils; 014 015 016/** 017 * Parser for plain, signed and encrypted JSON Web Tokens (JWTs). 018 * 019 * @author Vladimir Dzhuvinov 020 * @author Junya Hayashi 021 * @version $version$ (2014-11-14) 022 */ 023public final class JWTParser { 024 025 026 /** 027 * Parses a plain, signed or encrypted JSON Web Token (JWT) from the 028 * specified string in compact format. 029 * 030 * @param s The string to parse. Must not be {@code null}. 031 * 032 * @return The corresponding {@link PlainJWT}, {@link SignedJWT} or 033 * {@link EncryptedJWT} instance. 034 * 035 * @throws ParseException If the string couldn't be parsed to a valid 036 * plain, signed or encrypted JWT. 037 */ 038 public static JWT parse(final String s) 039 throws ParseException { 040 041 final int firstDotPos = s.indexOf("."); 042 043 if (firstDotPos == -1) 044 throw new ParseException("Invalid JWT serialization: Missing dot delimiter(s)", 0); 045 046 Base64URL header = new Base64URL(s.substring(0, firstDotPos)); 047 048 JSONObject jsonObject; 049 050 try { 051 jsonObject = JSONObjectUtils.parseJSONObject(header.decodeToString()); 052 053 } catch (ParseException e) { 054 055 throw new ParseException("Invalid plain/JWS/JWE header: " + e.getMessage(), 0); 056 } 057 058 Algorithm alg = Header.parseAlgorithm(jsonObject); 059 060 if (alg.equals(Algorithm.NONE)) { 061 return PlainJWT.parse(s); 062 } else if (alg instanceof JWSAlgorithm) { 063 return SignedJWT.parse(s); 064 } else if (alg instanceof JWEAlgorithm) { 065 return EncryptedJWT.parse(s); 066 } else { 067 throw new AssertionError("Unexpected algorithm type: " + alg); 068 } 069 } 070 071 072 /** 073 * Parses a plain, signed or encrypted JSON Web Token (JWT) from the 074 * specified string in compact format. 075 * 076 * @param s The string to parse. Must not be {@code null}. 077 * @param handler Handler for the parsed JWT. Must not be {@code null}. 078 * 079 * @return The object returned by the handler, {@code null} if none is 080 * returned. 081 * 082 * @throws ParseException If the string couldn't be parsed to a valid 083 * plain, signed or encrypted JWT. 084 */ 085 public static <T> T parse(final String s, final JWTHandler<T> handler) 086 throws ParseException { 087 088 JWT jwt = parse(s); 089 090 if (jwt instanceof PlainJWT) { 091 return handler.onPlainJWT((PlainJWT)jwt); 092 } else if (jwt instanceof SignedJWT) { 093 return handler.onSignedJWT((SignedJWT)jwt); 094 } else { 095 return handler.onEncryptedJWT((EncryptedJWT)jwt); 096 } 097 } 098 099 100 /** 101 * Prevents instantiation. 102 */ 103 private JWTParser() { 104 105 } 106}