/* * 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.security.Key; import java.util.Date; import java.util.Map; /** * A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT. * * @since 0.1 */ public interface JwtParser { /** * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not * a JWS (no signature), this key is not used. *
*
Note that this key MUST be a valid key for the signature algorithm found in the JWT header * (as the {@code alg} header parameter).
**
This method overwrites any previously set key.
* * @param key the algorithm-specific signature verification key used to validate any discovered JWS digital * signature. * @return the parser for method chaining. * @deprecated see {@link JwtParserBuilder#setSigningKey(byte[])}. * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an * immutable JwtParser. *NOTE: this method will be removed before version 1.0 */ @Deprecated JwtParser setSigningKey(byte[] key); /** * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not * a JWS (no signature), this key is not used. * *
Note that this key MUST be a valid key for the signature algorithm found in the JWT header * (as the {@code alg} header parameter).
* *This method overwrites any previously set key.
* *This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting * byte array is used to invoke {@link #setSigningKey(byte[])}.
* *This method has been deprecated because the {@code key} argument for this method can be confusing: keys for * cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were * obtained from the String argument.
* *This method always expected a String argument that was effectively the same as the result of the following * (pseudocode):
* *{@code String base64EncodedSecretKey = base64Encode(secretKeyBytes);}
* *However, a non-trivial number of JJWT users were confused by the method signature and attempted to * use raw password strings as the key argument - for example {@code setSigningKey(myPassword)} - which is * almost always incorrect for cryptographic hashes and can produce erroneous or insecure results.
* *See this * * StackOverflow answer explaining why raw (non-base64-encoded) strings are almost always incorrect for * signature operations.
* *Finally, please use the {@link #setSigningKey(Key) setSigningKey(Key)} instead, as this method and the * {@code byte[]} variant will be removed before the 1.0.0 release.
* * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signature verification key to use to validate * any discovered JWS digital signature. * @return the parser for method chaining. * @deprecated see {@link JwtParserBuilder#setSigningKey(String)}. * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an * immutable JwtParser. *NOTE: this method will be removed before version 1.0 */ @Deprecated JwtParser setSigningKey(String base64EncodedSecretKey); /** * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not * a JWS (no signature), this key is not used. *
*
Note that this key MUST be a valid key for the signature algorithm found in the JWT header * (as the {@code alg} header parameter).
**
This method overwrites any previously set key.
* * @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital * signature. * @return the parser for method chaining. * @deprecated see {@link JwtParserBuilder#setSigningKey(Key)}. * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an * immutable JwtParser. *NOTE: this method will be removed before version 1.0
*/
@Deprecated
JwtParser setSigningKey(Key key);
/**
* Sets the {@link SigningKeyResolver} used to acquire the signing key that should be used to verify
* a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used.
*
*
Specifying a {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing * the JWT and the JWT header or payload (plaintext body or Claims) must be inspected first to determine how to * look up the signing key. Once returned by the resolver, the JwtParser will then verify the JWS signature with the * returned key. For example:
**
* Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
* @Override
* public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
* //inspect the header or claims, lookup and return the signing key
* return getSigningKey(header, claims); //implement me
* }})
* .parseClaimsJws(compact);
*
* *
A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.
**
This method should only be used if a signing key is not provided by the other {@code setSigningKey*} builder * methods.
* * @param signingKeyResolver the signing key resolver used to retrieve the signing key. * @return the parser for method chaining. * @since 0.4 * @deprecated see {@link JwtParserBuilder#setSigningKeyResolver(SigningKeyResolver)}. * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an * immutable JwtParser. *NOTE: this method will be removed before version 1.0 */ @Deprecated JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver); /** * Parses the specified compact serialized JWT string based on the builder's current configuration state and * returns the resulting JWT or JWS instance. *
*
This method returns a JWT or JWS based on the parsed string. Because it may be cumbersome to determine if it * is a JWT or JWS, or if the body/payload is a Claims or String with {@code instanceof} checks, the * {@link #parse(String, JwtHandler) parse(String,JwtHandler)} method allows for a type-safe callback approach that * may help reduce code or instanceof checks.
* * @param jwt the compact serialized JWT to parse * @return the specified compact serialized JWT string based on the builder's current configuration state. * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). * Invalid * JWTs should not be trusted and should be discarded. * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail * signature validation should not be trusted and should be discarded. * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time * before the time this method is invoked. * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace. * @see #parse(String, JwtHandler) * @see #parsePlaintextJwt(String) * @see #parseClaimsJwt(String) * @see #parsePlaintextJws(String) * @see #parseClaimsJws(String) */ Jwt parse(String jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; /** * Parses the specified compact serialized JWT string based on the builder's current configuration state and * invokes the specified {@code handler} with the resulting JWT or JWS instance. **
If you are confident of the format of the JWT before parsing, you can create an anonymous subclass using the * {@link io.jsonwebtoken.JwtHandlerAdapter JwtHandlerAdapter} and override only the methods you know are relevant * for your use case(s), for example:
**
* String compactJwt = request.getParameter("jwt"); //we are confident this is a signed JWS
*
* String subject = Jwts.parser().setSigningKey(key).parse(compactJwt, new JwtHandlerAdapter<String>() {
* @Override
* public String onClaimsJws(Jws<Claims> jws) {
* return jws.getBody().getSubject();
* }
* });
*
* *
If you know the JWT string can be only one type of JWT, then it is even easier to invoke one of the * following convenience methods instead of this one:
**
*
This is a convenience method that is usable if you are confident that the compact string argument reflects an * unsigned plaintext JWT. An unsigned plaintext JWT has a String (non-JSON) body payload and it is not * cryptographically signed.
**
If the compact string presented does not reflect an unsigned plaintext JWT with non-JSON string body, * an {@link UnsupportedJwtException} will be thrown.
* * @param plaintextJwt a compact serialized unsigned plaintext JWT string. * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. * @throws UnsupportedJwtException if the {@code plaintextJwt} argument does not represent an unsigned plaintext * JWT * @throws MalformedJwtException if the {@code plaintextJwt} string is not a valid JWT * @throws SignatureException if the {@code plaintextJwt} string is actually a JWS and signature validation * fails * @throws IllegalArgumentException if the {@code plaintextJwt} string is {@code null} or empty or only whitespace * @see #parseClaimsJwt(String) * @see #parsePlaintextJws(String) * @see #parseClaimsJws(String) * @see #parse(String, JwtHandler) * @see #parse(String) * @since 0.2 */ Jwt*
This is a convenience method that is usable if you are confident that the compact string argument reflects an * unsigned Claims JWT. An unsigned Claims JWT has a {@link Claims} body and it is not cryptographically * signed.
**
If the compact string presented does not reflect an unsigned Claims JWT, an * {@link UnsupportedJwtException} will be thrown.
* * @param claimsJwt a compact serialized unsigned Claims JWT string. * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. * @throws UnsupportedJwtException if the {@code claimsJwt} argument does not represent an unsigned Claims JWT * @throws MalformedJwtException if the {@code claimsJwt} string is not a valid JWT * @throws SignatureException if the {@code claimsJwt} string is actually a JWS and signature validation * fails * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time * before the time this method is invoked. * @throws IllegalArgumentException if the {@code claimsJwt} string is {@code null} or empty or only whitespace * @see #parsePlaintextJwt(String) * @see #parsePlaintextJws(String) * @see #parseClaimsJws(String) * @see #parse(String, JwtHandler) * @see #parse(String) * @since 0.2 */ Jwt*
This is a convenience method that is usable if you are confident that the compact string argument reflects a * plaintext JWS. A plaintext JWS is a JWT with a String (non-JSON) body (payload) that has been * cryptographically signed.
**
If the compact string presented does not reflect a plaintext JWS, an {@link UnsupportedJwtException} * will be thrown.
* * @param plaintextJws a compact serialized JWS string. * @return the {@link Jws Jws} instance that reflects the specified compact JWS string. * @throws UnsupportedJwtException if the {@code plaintextJws} argument does not represent an plaintext JWS * @throws MalformedJwtException if the {@code plaintextJws} string is not a valid JWS * @throws SignatureException if the {@code plaintextJws} JWS signature validation fails * @throws IllegalArgumentException if the {@code plaintextJws} string is {@code null} or empty or only whitespace * @see #parsePlaintextJwt(String) * @see #parseClaimsJwt(String) * @see #parseClaimsJws(String) * @see #parse(String, JwtHandler) * @see #parse(String) * @since 0.2 */ Jws*
This is a convenience method that is usable if you are confident that the compact string argument reflects a * Claims JWS. A Claims JWS is a JWT with a {@link Claims} body that has been cryptographically signed.
**
If the compact string presented does not reflect a Claims JWS, an {@link UnsupportedJwtException} will be * thrown.
* * @param claimsJws a compact serialized Claims JWS string. * @return the {@link Jws Jws} instance that reflects the specified compact Claims JWS string. * @throws UnsupportedJwtException if the {@code claimsJws} argument does not represent an Claims JWS * @throws MalformedJwtException if the {@code claimsJws} string is not a valid JWS * @throws SignatureException if the {@code claimsJws} JWS signature validation fails * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time * before the time this method is invoked. * @throws IllegalArgumentException if the {@code claimsJws} string is {@code null} or empty or only whitespace * @see #parsePlaintextJwt(String) * @see #parseClaimsJwt(String) * @see #parsePlaintextJws(String) * @see #parse(String, JwtHandler) * @see #parse(String) * @since 0.2 */ Jws