JwtValidator { Jwt validate(String algorithm, ToBeSignedJwt target) throws InvalidAlgorithmParameterException, JwtExpiredException, JwtNotBeforeException, JwtInvalidException { validateTimestampClaims(target); if (!target.getAlgorithm().equals(algorithm)) { throw new InvalidAlgorithmParameterException( String.format( "invalid algorithm; expected %s, got %s", algorithm, target.getAlgorithm())); } @SuppressWarnings("unchecked") Iterator<String> headerIterator = this.header.keys(); while (headerIterator.hasNext()) { String name = headerIterator.next(); if (name.equals(JwtNames.HEADER_ALGORITHM)) { continue; } String value = target.getHeader(name); if (value == null || !value.equals(this.getHeader(name))) { throw new JwtInvalidException( String.format( "invalid JWT; expected header '%s' with value %s, but got %s", name, value, this.getHeader(name))); } } @SuppressWarnings("unchecked") Iterator<String> payloadIterator = this.payload.keys(); while (payloadIterator.hasNext()) { String name = payloadIterator.next(); if (name.equals(JwtNames.CLAIM_AUDIENCE)) { continue; } Object value = target.getClaim(name); if (value == null || !value.equals(this.getClaim(name))) { throw new JwtInvalidException( String.format( "invalid JWT; expected claim '%s' with value %s, but got %s", name, value, this.getClaim(name))); } } List<String> audiences = target.getAudiences(); String audience = (String) this.getClaim(JwtNames.CLAIM_AUDIENCE); if ((audiences == null && audience != null) || (audiences != null && !audiences.contains(audience))) { throw new JwtInvalidException( String.format( "invalid JWT; cannot find the expected audience %s in claimed audiences %s", audience, audiences)); } return new Jwt(target.getHeader(), target.getPayload(), this.clock, this.clockSkew); } private  JwtValidator(Builder builder);   }
@Test public void validate_noAlgorithm_shouldThrow() throws Exception { String algo = "HS256"; JwtValidator validator = new JwtValidator.Builder().build(); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().build(); assertThrows(IllegalStateException.class, () -> validator.validate(algo, unverified)); }
@Test public void validate_wrongAlgorithm_shouldThrow() throws Exception { String algo = "HS256"; JwtValidator validator = new JwtValidator.Builder().build(); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm(algo).build(); assertThrows( InvalidAlgorithmParameterException.class, () -> validator.validate("blah", unverified)); }
@Test public void validate_algorithm_success() throws Exception { String algo = "HS256"; JwtValidator validator = new JwtValidator.Builder().build(); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm(algo).build(); Jwt token = validator.validate(algo, unverified); assertThat(token.getAlgorithm()).isEqualTo(algo); }
@Test public void validate_expired_shouldThrow() throws Exception { String algo = "HS256"; Clock clock1 = Clock.systemUTC(); ToBeSignedJwt token = new ToBeSignedJwt.Builder() .setAlgorithm(algo) .setExpiration(clock1.instant().plus(Duration.ofMinutes(1))) .build(); Clock clock2 = Clock.offset(clock1, Duration.ofMinutes(2)); JwtValidator validator = new JwtValidator.Builder().setClock(clock2).build(); assertThrows(JwtExpiredException.class, () -> validator.validate(algo, token)); }
@Test public void validate_notExpired_success() throws Exception { String algo = "HS256"; Clock clock = Clock.systemUTC(); Instant expiration = clock.instant().plus(Duration.ofMinutes(1)); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm(algo).setExpiration(expiration).build(); JwtValidator validator = new JwtValidator.Builder().build(); Jwt token = validator.validate(algo, unverified); assertThat(token.getExpiration().getEpochSecond()).isEqualTo(expiration.getEpochSecond()); }
@Test public void validate_notExpired_clockSkew_success() throws Exception { String algo = "HS256"; Clock clock1 = Clock.systemUTC(); Instant expiration = clock1.instant().plus(Duration.ofMinutes(1)); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm(algo).setExpiration(expiration).build(); JwtValidator validator = new JwtValidator.Builder().setClockSkew(Duration.ofMinutes(1)).build(); Jwt token = validator.validate(algo, unverified); assertThat(token.getExpiration().getEpochSecond()).isEqualTo(expiration.getEpochSecond()); }
@Test public void validate_before_shouldThrow() throws Exception { String algo = "HS256"; Clock clock = Clock.systemUTC(); Instant notBefore = clock.instant().plus(Duration.ofMinutes(1)); ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm(algo).setNotBefore(notBefore).build(); JwtValidator validator = new JwtValidator.Builder().build(); assertThrows(JwtNotBeforeException.class, () -> validator.validate(algo, token)); }
@Test public void validate_notBefore_success() throws Exception { String algo = "HS256"; Clock clock1 = Clock.systemUTC(); Instant notBefore = clock1.instant().plus(Duration.ofMinutes(1)); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm(algo).setNotBefore(notBefore).build(); Clock clock2 = Clock.offset(clock1, Duration.ofMinutes(2)); JwtValidator validator = new JwtValidator.Builder().setClock(clock2).build(); Jwt token = validator.validate(algo, unverified); assertThat(token.getNotBefore().getEpochSecond()).isEqualTo(notBefore.getEpochSecond()); }
@Test public void validate_notBefore_clockSkew_success() throws Exception { String algo = "HS256"; Clock clock1 = Clock.systemUTC(); Instant notBefore = clock1.instant().plus(Duration.ofMinutes(1)); ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm(algo).setNotBefore(notBefore).build(); JwtValidator validator = new JwtValidator.Builder().setClockSkew(Duration.ofMinutes(1)).build(); Jwt token = validator.validate(algo, unverified); assertThat(token.getNotBefore().getEpochSecond()).isEqualTo(notBefore.getEpochSecond()); }
@Test public void validate_noType_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setType("JWT").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_wrongType_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setType("blah").build(); JwtValidator validator = new JwtValidator.Builder().setType("JWT").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_type_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setType("JWT").build(); JwtValidator validator = new JwtValidator.Builder().setType("JWT").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getType()).isEqualTo("JWT"); }
@Test public void validate_noContentType_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setContentType("JWT").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_wrongContentType_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setContentType("blah").build(); JwtValidator validator = new JwtValidator.Builder().setContentType("JWT").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_contentType_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setContentType("foo").build(); JwtValidator validator = new JwtValidator.Builder().setContentType("foo").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getContentType()).isEqualTo("foo"); }
@Test public void validate_noKeyId_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setKeyId("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_wrongKeyId_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setKeyId("blah").build(); JwtValidator validator = new JwtValidator.Builder().setKeyId("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_keyId_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setKeyId("123").build(); JwtValidator validator = new JwtValidator.Builder().setKeyId("123").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getKeyId()).isEqualTo("123"); }
@Test public void validate_noIssuer_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setIssuer("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_wrongIssuer_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setIssuer("blah").build(); JwtValidator validator = new JwtValidator.Builder().setIssuer("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_issuer_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setIssuer("123").build(); JwtValidator validator = new JwtValidator.Builder().setIssuer("123").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getIssuer()).isEqualTo("123"); }
@Test public void validate_noSubject_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setSubject("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_wrongSubject_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setSubject("blah").build(); JwtValidator validator = new JwtValidator.Builder().setSubject("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_subject_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setSubject("123").build(); JwtValidator validator = new JwtValidator.Builder().setSubject("123").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getSubject()).isEqualTo("123"); }
@Test public void validate_noJwtId_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setJwtId("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_wrongJwtId_shouldThrow() throws Exception { ToBeSignedJwt token = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setJwtId("blah").build(); JwtValidator validator = new JwtValidator.Builder().setJwtId("123").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", token)); }
@Test public void validate_jwtId_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").setJwtId("123").build(); JwtValidator validator = new JwtValidator.Builder().setJwtId("123").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getJwtId()).isEqualTo("123"); }
@Test public void validate_noAudienceInJwt_shouldThrow() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").build(); JwtValidator validator = new JwtValidator.Builder().setAudience("foo").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", unverified)); }
@Test public void validate_noAudienceInValidator_shouldThrow() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").addAudience("foo").build(); JwtValidator validator = new JwtValidator.Builder().build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", unverified)); }
@Test public void validate_wrongAudience_shouldThrow() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").addAudience("foo").build(); JwtValidator validator = new JwtValidator.Builder().setAudience("bar").build(); assertThrows(JwtInvalidException.class, () -> validator.validate("HS256", unverified)); }
@Test public void validate_audience_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder().setAlgorithm("HS256").addAudience("foo").build(); JwtValidator validator = new JwtValidator.Builder().setAudience("foo").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getAudiences()).containsExactly("foo"); }
@Test public void validate_multipleAudiences_success() throws Exception { ToBeSignedJwt unverified = new ToBeSignedJwt.Builder() .setAlgorithm("HS256") .addAudience("foo") .addAudience("bar") .build(); JwtValidator validator = new JwtValidator.Builder().setAudience("bar").build(); Jwt token = validator.validate("HS256", unverified); assertThat(token.getAudiences()).containsExactly("foo", "bar"); }