Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright 2010 Google Inc.
*
* 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 net.oauth.jsontoken;
import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.oauth.jsontoken.crypto.AsciiStringVerifier;
import net.oauth.jsontoken.crypto.SignatureAlgorithm;
import net.oauth.jsontoken.crypto.Verifier;
import net.oauth.jsontoken.discovery.VerifierProviders;
import org.apache.commons.codec.binary.Base64;
import org.joda.time.Instant;
import java.security.SignatureException;
import java.util.List;
import java.util.regex.Pattern;
/**
* Class that parses and verifies JSON Tokens.
*/
public class JsonTokenParser {
private final Clock clock;
private final VerifierProviders verifierProviders;
private final Checker[] checkers;
/**
* Creates a new {@link JsonTokenParser} with a default system clock. The default
* system clock tolerates a clock skew of up to {@link SystemClock#DEFAULT_ACCEPTABLE_CLOCK_SKEW}.
*
* @param verifierProviders an object that provides signature verifiers
* based on a signature algorithm, the signer, and key ids.
* @param checker an audience checker that validates the audience in the JSON token.
*/
public JsonTokenParser(VerifierProviders verifierProviders, Checker checker) {
this(new SystemClock(), verifierProviders, checker);
}
/**
* Creates a new {@link JsonTokenParser}.
*
* @param clock a clock object that will decide whether a given token is
* currently valid or not.
* @param verifierProviders an object that provides signature verifiers
* based on a signature algorithm, the signer, and key ids.
* @param checkers an array of checkers that validates the parameters in the JSON token.
*/
public JsonTokenParser(Clock clock, VerifierProviders verifierProviders, Checker... checkers) {
this.clock = Preconditions.checkNotNull(clock);
this.verifierProviders = verifierProviders;
this.checkers = checkers;
}
/**
* Decodes the JWT token string into a JsonToken object. Does not perform
* any validation of headers or claims.
*
* @param tokenString The original encoded representation of a JWT
* @return Unverified contents of the JWT as a JsonToken
*/
public JsonToken deserialize(String tokenString) {
String[] pieces = splitTokenString(tokenString);
String jwtHeaderSegment = pieces[0];
String jwtPayloadSegment = pieces[1];
byte[] signature = Base64.decodeBase64(pieces[2]);
JsonParser parser = new JsonParser();
JsonObject header = parser.parse(JsonTokenUtil.fromBase64ToJsonString(jwtHeaderSegment))
.getAsJsonObject();
JsonObject payload = parser.parse(JsonTokenUtil.fromBase64ToJsonString(jwtPayloadSegment))
.getAsJsonObject();
JsonToken jsonToken = new JsonToken(header, payload, clock, tokenString);
return jsonToken;
}
/**
* Verifies that the jsonToken has a valid signature and valid standard claims
* (iat, exp). Uses VerifierProviders to obtain the secret key.
*
* @param jsonToken
* @throws SignatureException
*/
public void verify(JsonToken jsonToken) throws SignatureException {
List verifiers = provideVerifiers(jsonToken);
verify(jsonToken, verifiers);
}
/**
* Parses, and verifies, a JSON Token.
*
* @param tokenString the serialized token that is to parsed and verified.
* @return the deserialized {@link JsonObject}, suitable for passing to the constructor
* of {@link JsonToken} or equivalent constructor of {@link JsonToken} subclasses.
* @throws SignatureException
*/
public JsonToken verifyAndDeserialize(String tokenString) throws SignatureException {
JsonToken jsonToken = deserialize(tokenString);
verify(jsonToken);
return jsonToken;
}
/**
* Verifies that the jsonToken has a valid signature and valid standard claims
* (iat, exp). Does not need VerifierProviders because verifiers are passed in
* directly.
*
* @param jsonToken the token to verify
* @throws SignatureException when the signature is invalid
* @throws IllegalStateException when exp or iat are invalid
*/
public void verify(JsonToken jsonToken, List verifiers) throws SignatureException {
if (! signatureIsValid(jsonToken.getTokenString(), verifiers)) {
throw new SignatureException("Invalid signature for token: " +
jsonToken.getTokenString());
}
Instant issuedAt = jsonToken.getIssuedAt();
Instant expiration = jsonToken.getExpiration();
if (issuedAt == null && expiration != null) {
issuedAt = new Instant(0);
}
if (issuedAt != null && expiration == null) {
expiration = new Instant(Long.MAX_VALUE);
}
if (issuedAt != null && expiration != null) {
if (issuedAt.isAfter(expiration)
|| ! clock.isCurrentTimeInInterval(issuedAt, expiration)) {
throw new IllegalStateException(String.format("Invalid iat and/or exp. iat: %s exp: %s "
+ "now: %s", jsonToken.getIssuedAt(), jsonToken.getExpiration(), clock.now()));
}
}
if (checkers != null) {
for (Checker checker : checkers) {
checker.check(jsonToken.getPayloadAsJsonObject());
}
}
}
/**
* Verifies that a JSON Web Token's signature is valid.
*
* @param tokenString the encoded and signed JSON Web Token to verify.
* @param verifiers used to verify the signature. These usually encapsulate
* secret keys.
*/
public boolean signatureIsValid(String tokenString, List verifiers) {
String[] pieces = splitTokenString(tokenString);
byte[] signature = Base64.decodeBase64(pieces[2]);
String baseString = JsonTokenUtil.toDotFormat(pieces[0], pieces[1]);
boolean sigVerified = false;
for (Verifier verifier : verifiers) {
AsciiStringVerifier asciiVerifier = new AsciiStringVerifier(verifier);
try {
asciiVerifier.verifySignature(baseString, signature);
sigVerified = true;
break;
} catch (SignatureException e) {
continue;
}
}
return sigVerified;
}
/**
* Verifies that a JSON Web Token is not expired.
*
* @param jsonToken the token to verify
* @param now the instant to use as point of reference for current time
* @return false if the token is expired, true otherwise
*/
public boolean expirationIsValid(JsonToken jsonToken, Instant now) {
Instant expiration = jsonToken.getExpiration();
if ((expiration != null) && now.isAfter(expiration)) {
return false;
}
return true;
}
/**
* Verifies that a JSON Web Token was issued in the past.
*
* @param jsonToken the token to verify
* @param now the instant to use as point of reference for current time
* @return false if the JWT's 'iat' is later than now, true otherwise
*/
public boolean issuedAtIsValid(JsonToken jsonToken, Instant now) {
Instant issuedAt = jsonToken.getIssuedAt();
if ((issuedAt != null) && now.isBefore(issuedAt)) {
return false;
}
return true;
}
/**
* Use VerifierProviders to get a list of verifiers for this token
*
* @param jsonToken
* @return list of verifiers
* @throws SignatureException
*/
private List provideVerifiers(JsonToken jsonToken) throws SignatureException {
Preconditions.checkNotNull(verifierProviders);
JsonObject header = jsonToken.getHeader();
JsonElement keyIdJson = header.get(JsonToken.KEY_ID_HEADER);
String keyId = (keyIdJson == null) ? null : keyIdJson.getAsString();
SignatureAlgorithm sigAlg = jsonToken.getSignatureAlgorithm();
List verifiers = verifierProviders.getVerifierProvider(sigAlg)
.findVerifier(jsonToken.getIssuer(), keyId);
if (verifiers == null) {
throw new IllegalStateException("No valid verifier for issuer: " + jsonToken.getIssuer());
}
return verifiers;
}
/**
* @param tokenString The original encoded representation of a JWT
* @return Three components of the JWT as an array of strings
*/
private String[] splitTokenString(String tokenString) {
String[] pieces = tokenString.split(Pattern.quote(JsonTokenUtil.DELIMITER));
if (pieces.length != 3) {
throw new IllegalStateException("Expected JWT to have 3 segments separated by '" +
JsonTokenUtil.DELIMITER + "', but it has " + pieces.length + " segments");
}
return pieces;
}
}