|
1 | 1 | package com.auth0.jwt; |
2 | 2 |
|
3 | 3 | import com.auth0.jwt.algorithms.Algorithm; |
4 | | -import com.auth0.jwt.exceptions.AlgorithmMismatchException; |
5 | | -import com.auth0.jwt.exceptions.InvalidClaimException; |
6 | | -import com.auth0.jwt.exceptions.JWTVerificationException; |
7 | | -import com.auth0.jwt.exceptions.SignatureVerificationException; |
8 | | -import com.auth0.jwt.exceptions.TokenExpiredException; |
| 4 | +import com.auth0.jwt.exceptions.*; |
9 | 5 | import com.auth0.jwt.impl.PublicClaims; |
10 | 6 | import com.auth0.jwt.interfaces.Claim; |
11 | 7 | import com.auth0.jwt.interfaces.Clock; |
12 | 8 | import com.auth0.jwt.interfaces.DecodedJWT; |
13 | 9 | import com.auth0.jwt.interfaces.Verification; |
14 | | -import org.apache.commons.codec.binary.Base64; |
15 | 10 |
|
16 | | -import java.nio.charset.StandardCharsets; |
17 | 11 | import java.util.*; |
18 | 12 |
|
19 | 13 | /** |
@@ -349,29 +343,26 @@ private void requireClaim(String name, Object value) { |
349 | 343 | * |
350 | 344 | * @param token to verify. |
351 | 345 | * @return a verified and decoded JWT. |
352 | | - * @throws JWTVerificationException if any of the required contents inside the JWT is invalid. |
| 346 | + * @throws AlgorithmMismatchException if the algorithm stated in the token's header it's not equal to the one defined in the {@link JWTVerifier}. |
| 347 | + * @throws SignatureVerificationException if the signature is invalid. |
| 348 | + * @throws TokenExpiredException if the token has expired. |
| 349 | + * @throws InvalidClaimException if a claim contained a different value than the expected one. |
353 | 350 | */ |
354 | 351 | public DecodedJWT verify(String token) throws JWTVerificationException { |
355 | | - DecodedJWT jwt = JWTDecoder.decode(token); |
| 352 | + DecodedJWT jwt = JWT.decode(token); |
356 | 353 | verifyAlgorithm(jwt, algorithm); |
357 | | - verifySignature(TokenUtils.splitToken(token)); |
| 354 | + algorithm.verify(jwt); |
358 | 355 | verifyClaims(jwt, claims); |
359 | 356 | return jwt; |
360 | 357 | } |
361 | 358 |
|
362 | | - private void verifySignature(String[] parts) throws SignatureVerificationException { |
363 | | - byte[] content = String.format("%s.%s", parts[0], parts[1]).getBytes(StandardCharsets.UTF_8); |
364 | | - byte[] signature = Base64.decodeBase64(parts[2]); |
365 | | - algorithm.verify(content, signature); |
366 | | - } |
367 | | - |
368 | 359 | private void verifyAlgorithm(DecodedJWT jwt, Algorithm expectedAlgorithm) throws AlgorithmMismatchException { |
369 | 360 | if (!expectedAlgorithm.getName().equals(jwt.getAlgorithm())) { |
370 | 361 | throw new AlgorithmMismatchException("The provided Algorithm doesn't match the one defined in the JWT's Header."); |
371 | 362 | } |
372 | 363 | } |
373 | 364 |
|
374 | | - private void verifyClaims(DecodedJWT jwt, Map<String, Object> claims) { |
| 365 | + private void verifyClaims(DecodedJWT jwt, Map<String, Object> claims) throws TokenExpiredException, InvalidClaimException { |
375 | 366 | for (Map.Entry<String, Object> entry : claims.entrySet()) { |
376 | 367 | switch (entry.getKey()) { |
377 | 368 | case PublicClaims.AUDIENCE: |
@@ -435,31 +426,28 @@ private void assertValidStringClaim(String claimName, String value, String expec |
435 | 426 | } |
436 | 427 |
|
437 | 428 | private void assertValidDateClaim(Date date, long leeway, boolean shouldBeFuture) { |
438 | | - Date today = clock.getToday(); |
439 | | - today.setTime((long) Math.floor((today.getTime() / 1000) * 1000)); // truncate |
440 | | - // millis |
441 | | - if (shouldBeFuture) { |
442 | | - assertDateIsFuture(date, leeway, today); |
443 | | - } else { |
444 | | - assertDateIsPast(date, leeway, today); |
445 | | - } |
446 | | - } |
447 | | - |
448 | | - private void assertDateIsFuture(Date date, long leeway, Date today) { |
449 | | - |
450 | | - today.setTime(today.getTime() - leeway * 1000); |
451 | | - if (date != null && today.after(date)) { |
452 | | - throw new TokenExpiredException(String.format("The Token has expired on %s.", date)); |
453 | | - } |
454 | | - } |
455 | | - |
456 | | - private void assertDateIsPast(Date date, long leeway, Date today) { |
457 | | - today.setTime(today.getTime() + leeway * 1000); |
458 | | - if(date!=null && today.before(date)) { |
459 | | - throw new InvalidClaimException(String.format("The Token can't be used before %s.", date)); |
460 | | - } |
461 | | - |
462 | | - } |
| 429 | + Date today = clock.getToday(); |
| 430 | + today.setTime((long) Math.floor((today.getTime() / 1000) * 1000)); // truncate millis |
| 431 | + if (shouldBeFuture) { |
| 432 | + assertDateIsFuture(date, leeway, today); |
| 433 | + } else { |
| 434 | + assertDateIsPast(date, leeway, today); |
| 435 | + } |
| 436 | + } |
| 437 | + |
| 438 | + private void assertDateIsFuture(Date date, long leeway, Date today) { |
| 439 | + today.setTime(today.getTime() - leeway * 1000); |
| 440 | + if (date != null && today.after(date)) { |
| 441 | + throw new TokenExpiredException(String.format("The Token has expired on %s.", date)); |
| 442 | + } |
| 443 | + } |
| 444 | + |
| 445 | + private void assertDateIsPast(Date date, long leeway, Date today) { |
| 446 | + today.setTime(today.getTime() + leeway * 1000); |
| 447 | + if (date != null && today.before(date)) { |
| 448 | + throw new InvalidClaimException(String.format("The Token can't be used before %s.", date)); |
| 449 | + } |
| 450 | + } |
463 | 451 |
|
464 | 452 | private void assertValidAudienceClaim(List<String> audience, List<String> value) { |
465 | 453 | if (audience == null || !audience.containsAll(value)) { |
|
0 commit comments