Search

jwt

@Override publicJws<Claims> parseClaimsJws(String claimsJws) { return parse(claimsJws,newJwtHandlerAdapter<Jws<Claims>>() { @Override public Jws<Claims> onClaimsJws(Jws<Claims> jws) { return jws; } }); }
Plain Text
볡사
@Override public<T> T parse(String compact,JwtHandler<T> handler) throwsExpiredJwtException, MalformedJwtException, SignatureException { Assert.notNull(handler, "JwtHandler argument cannot be null."); Assert.hasText(compact, "JWT String argument cannot be null or empty."); Jwtjwt = parse(compact); if(jwtinstanceofJws) { Jwsjws = (Jws) jwt; Object body = jws.getBody(); if(bodyinstanceofClaims) { returnhandler.onClaimsJws((Jws<Claims>) jws); }else{ returnhandler.onPlaintextJws((Jws<String>) jws); } }else{ Object body = jwt.getBody(); if(bodyinstanceofClaims) { returnhandler.onClaimsJwt((Jwt<Header,Claims>) jwt); }else{ returnhandler.onPlaintextJwt((Jwt<Header, String>) jwt); } } }
Plain Text
볡사
@Override publicJwtparse(String jwt)throwsExpiredJwtException, MalformedJwtException, SignatureException { // TODO, this logic is only need for a now deprecated code path // remove this block in v1.0 (the equivalent is already in DefaultJwtParserBuilder) if(this.deserializer ==null) { // try to find one based on the services available // TODO: This util class will throw a UnavailableImplementationException here to retain behavior of previous version, remove in v1.0 this.deserializer = LegacyServices.loadFirst(Deserializer.class); } Assert.hasText(jwt, "JWT String argument cannot be null or empty."); if("..".equals(jwt)) { String msg = "JWT string '..' is missing a header."; throw newMalformedJwtException(msg); } String base64UrlEncodedHeader =null; String base64UrlEncodedPayload =null; String base64UrlEncodedDigest =null; intdelimiterCount = 0; StringBuilder sb =newStringBuilder(128); for(charc : jwt.toCharArray()) { if(c ==SEPARATOR_CHAR) { CharSequencetokenSeq = Strings.clean(sb); String token = tokenSeq !=null? tokenSeq.toString() :null; if(delimiterCount == 0) { base64UrlEncodedHeader = token; }else if(delimiterCount == 1) { base64UrlEncodedPayload = token; } delimiterCount++; sb.setLength(0); }else{ sb.append(c); } } if(delimiterCount != 2) { String msg = "JWT strings must contain exactly 2 period characters. Found: " + delimiterCount; throw newMalformedJwtException(msg); } if(sb.length() > 0) { base64UrlEncodedDigest = sb.toString(); } // =============== Header ================= Headerheader =null; CompressionCodeccompressionCodec =null; if(base64UrlEncodedHeader !=null) { byte[] bytes = base64UrlDecoder.decode(base64UrlEncodedHeader); String origValue =newString(bytes, Strings.UTF_8); Map<String, Object> m = (Map<String, Object>) readValue(origValue); if(base64UrlEncodedDigest !=null) { header =newDefaultJwsHeader(m); }else{ header =newDefaultHeader(m); } compressionCodec = compressionCodecResolver.resolveCompressionCodec(header); } // =============== Body ================= String payload = "";//https://github.com/jwtk/jjwt/pull/540 if(base64UrlEncodedPayload !=null) { byte[] bytes = base64UrlDecoder.decode(base64UrlEncodedPayload); if(compressionCodec !=null) { bytes = compressionCodec.decompress(bytes); } payload =newString(bytes, Strings.UTF_8); } Claimsclaims =null; if(!payload.isEmpty() && payload.charAt(0) == '{' && payload.charAt(payload.length() - 1) == '}') {//likely to be json, parse it: Map<String, Object> claimsMap = (Map<String, Object>) readValue(payload); claims =newDefaultClaims(claimsMap); } // =============== Signature ================= if(base64UrlEncodedDigest !=null) {//it is signed - validate the signature JwsHeaderjwsHeader = (JwsHeader) header; SignatureAlgorithm algorithm =null; if(header !=null) { String alg = jwsHeader.getAlgorithm(); if(Strings.hasText(alg)) { algorithm = SignatureAlgorithm.forName(alg); } } if(algorithm ==null|| algorithm == SignatureAlgorithm.NONE) { //it is plaintext, but it has a signature. This is invalid: String msg = "JWT string has a digest/signature, but the header does not reference a valid signature " + "algorithm."; throw newMalformedJwtException(msg); } if(key !=null&& keyBytes !=null) { throw newIllegalStateException("A key object and key bytes cannot both be specified. Choose either."); }else if((key !=null|| keyBytes !=null) && signingKeyResolver !=null) { String object = key !=null? "a key object" : "key bytes"; throw newIllegalStateException("A signing key resolver and " + object + " cannot both be specified. Choose either."); } //digitally signed, let's assert the signature: Keykey =this.key; if(key ==null) {//fall back to keyBytes byte[] keyBytes =this.keyBytes; if(Objects.isEmpty(keyBytes) && signingKeyResolver !=null) {//use the signingKeyResolver if(claims !=null) { key = signingKeyResolver.resolveSigningKey(jwsHeader, claims); }else{ key = signingKeyResolver.resolveSigningKey(jwsHeader, payload); } } if(!Objects.isEmpty(keyBytes)) { Assert.isTrue(algorithm.isHmac(), "Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance."); key =newSecretKeySpec(keyBytes, algorithm.getJcaName()); } } Assert.notNull(key, "A signing key must be specified if the specified JWT is digitally signed."); //re-create the jwt part without the signature. This is what needs to be signed for verification: String jwtWithoutSignature = base64UrlEncodedHeader +SEPARATOR_CHAR; if(base64UrlEncodedPayload !=null) { jwtWithoutSignature += base64UrlEncodedPayload; } JwtSignatureValidatorvalidator; try{ algorithm.assertValidVerificationKey(key);//since 0.10.0:https://github.com/jwtk/jjwt/issues/334 validator = createSignatureValidator(algorithm, key); }catch(WeakKeyException e) { throwe; }catch(InvalidKeyException | IllegalArgumentException e) { String algName = algorithm.getValue(); String msg = "The parsed JWT indicates it was signed with the " + algName + " signature " + "algorithm, but the specified signing key of type " + key.getClass().getName() + " may not be used to validate " + algName + " signatures. Because the specified " + "signing key reflects a specific and expected algorithm, and the JWT does not reflect " + "this algorithm, it is likely that the JWT was not expected and therefore should not be " + "trusted. Another possibility is that the parser was configured with the incorrect " + "signing key, but this cannot be assumed for security reasons."; throw newUnsupportedJwtException(msg, e); } if(!validator.isValid(jwtWithoutSignature, base64UrlEncodedDigest)) { String msg = "JWT signature does not match locally computed signature. JWT validity cannot be " + "asserted and should not be trusted."; throw newSignatureException(msg); } } final booleanallowSkew =this.allowedClockSkewMillis > 0; //since 0.3: if(claims !=null) { finalDate now =this.clock.now(); longnowTime = now.getTime(); //https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.4 //token MUST NOT be accepted on or after any specified exp time: Date exp = claims.getExpiration(); if(exp !=null) { longmaxTime = nowTime -this.allowedClockSkewMillis; Date max = allowSkew ?newDate(maxTime) : now; if(max.after(exp)) { String expVal = DateFormats.formatIso8601(exp,false); String nowVal = DateFormats.formatIso8601(now,false); longdifferenceMillis = maxTime - exp.getTime(); String msg = "JWT expired at " + expVal + ". Current time: " + nowVal + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw newExpiredJwtException(header, claims, msg); } } //https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.5 //token MUST NOT be accepted before any specified nbf time: Date nbf = claims.getNotBefore(); if(nbf !=null) { longminTime = nowTime +this.allowedClockSkewMillis; Date min = allowSkew ?newDate(minTime) : now; if(min.before(nbf)) { String nbfVal = DateFormats.formatIso8601(nbf,false); String nowVal = DateFormats.formatIso8601(now,false); longdifferenceMillis = nbf.getTime() - minTime; String msg = "JWT must not be accepted before " + nbfVal + ". Current time: " + nowVal + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw newPrematureJwtException(header, claims, msg); } } validateExpectedClaims(header, claims); } Object body = claims !=null? claims : payload; if(base64UrlEncodedDigest !=null) { return newDefaultJws<>((JwsHeader) header, body, base64UrlEncodedDigest); }else{ return newDefaultJwt<>(header, body); } }
Plain Text
볡사