Skip to content

Commit

Permalink
Bump jjwt.version from 0.11.5 to 0.12.5 (#17075)
Browse files Browse the repository at this point in the history
* Bump jjwt.version from 0.11.5 to 0.12.3

Bumps `jjwt.version` from 0.11.5 to 0.12.3.

Updates `io.jsonwebtoken:jjwt-api` from 0.11.5 to 0.12.3
- [Release notes](https://github.com/jwtk/jjwt/releases)
- [Changelog](https://github.com/jwtk/jjwt/blob/master/CHANGELOG.md)
- [Commits](jwtk/jjwt@0.11.5...0.12.3)

Updates `io.jsonwebtoken:jjwt-impl` from 0.11.5 to 0.12.3
- [Release notes](https://github.com/jwtk/jjwt/releases)
- [Changelog](https://github.com/jwtk/jjwt/blob/master/CHANGELOG.md)
- [Commits](jwtk/jjwt@0.11.5...0.12.3)

Updates `io.jsonwebtoken:jjwt-jackson` from 0.11.5 to 0.12.3

---
updated-dependencies:
- dependency-name: io.jsonwebtoken:jjwt-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: io.jsonwebtoken:jjwt-impl
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: io.jsonwebtoken:jjwt-jackson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* fixed JwtTokenValidator

* adapt jwt token test for NONE alg

* trim imported licenses in integration tests

* Added changelog

* Added changelog

* code cleanup, removed changelog, added test

* code cleanup

* Update to jjwt 0.12.5

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tomas Dvorak <[email protected]>
Co-authored-by: Bernd Ahlers <[email protected]>
Co-authored-by: Bernd Ahlers <[email protected]>
  • Loading branch information
4 people authored Feb 27, 2024
1 parent 527da6b commit 54ff42b
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,15 @@
*/
package org.graylog.datanode.initializers;

import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.security.Keys;
import jakarta.inject.Named;
import jakarta.inject.Singleton;

import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Optional;

@Singleton
public class JwtTokenValidator implements AuthTokenValidator {
Expand All @@ -41,30 +39,18 @@ public JwtTokenValidator(@Named("password_secret") final String signingKey) {

@Override
public void verifyToken(String token) throws TokenVerificationException {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
Key signingKey = new SecretKeySpec(this.signingKey.getBytes(StandardCharsets.UTF_8), signatureAlgorithm.getJcaName());
final JwtParser parser = Jwts.parserBuilder()
.setSigningKey(signingKey)
final SecretKey key = Keys.hmacShaKeyFor(this.signingKey.getBytes(StandardCharsets.UTF_8));
final JwtParser parser = Jwts.parser()
.verifyWith(key)
.requireSubject(REQUIRED_SUBJECT)
.requireIssuer(REQUIRED_ISSUER)
.build();
try {
final Jwt parsed = parser.parse(token);
verifySignature(parsed, signatureAlgorithm);
} catch (Exception e) {
parser.parse(token);
} catch (UnsupportedJwtException e) {
throw new TokenVerificationException("Token format/configuration is not supported", e);
} catch (Throwable e) {
throw new TokenVerificationException(e);
}
}

private void verifySignature(Jwt token, SignatureAlgorithm expectedAlgorithm) {
final SignatureAlgorithm usedAlgorithm = Optional.of(token.getHeader())
.map(h -> h.get("alg"))
.map(Object::toString)
.map(SignatureAlgorithm::forName)
.orElseThrow(() -> new IllegalArgumentException("Token doesn't provide valid signature algorithm"));

if (expectedAlgorithm != usedAlgorithm) {
throw new IllegalArgumentException("Token is using unsupported signature algorithm :" + usedAlgorithm);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
package org.graylog.datanode.initializers;

public class TokenVerificationException extends Exception {
public TokenVerificationException(Exception cause) {
public TokenVerificationException(Throwable cause) {
super(cause);
}

public TokenVerificationException(String message) {
super(message);
}

public TokenVerificationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
package org.graylog.datanode.initializers;

import com.github.joschi.jadconfig.util.Duration;
import org.assertj.core.api.Assertions;
import org.graylog2.security.IndexerJwtAuthTokenProvider;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

class JwtTokenValidatorTest {

@Test
void verifyValidToken() throws TokenVerificationException {
final String key = "gTVfiF6A0pB70A3UP1EahpoR6LId9DdNadIkYNygK5Z8lpeJIpw9vN0jZ6fdsfeuV9KIg9gVLkCHIPj6FHW5Q9AvpOoGZO3h";
final JwtTokenValidator validator = new JwtTokenValidator(key);
validator.verifyToken(generateToken(key));
}

@Test
void verifyInvalidToken() {
final String generationKey = "gTVfiF6A0pB70A3UP1EahpoR6LId9DdNadIkYNygK5Z8lpeJIpw9vN0jZ6fdsfeuV9KIg9gVLkCHIPj6FHW5Q9AvpOoGZO3h";
final String verificationKey = "n51wcO3jn8w3JNyGgKc7k1fTCr1FWvGg7ODfQOyBT2fizBrCVsRJg2GsbYGLNejfi3QsKaqJgo3zAWMuAZhJznuizHZpv92S";
final JwtTokenValidator validator = new JwtTokenValidator(verificationKey);
Assertions.assertThatThrownBy(() -> validator.verifyToken(generateToken(generationKey)))
.isInstanceOf(TokenVerificationException.class)
.hasMessageContaining("JWT signature does not match locally computed signature");
}

@Test
void testNoneAlgorithm() {
final String key = "gTVfiF6A0pB70A3UP1EahpoR6LId9DdNadIkYNygK5Z8lpeJIpw9vN0jZ6fdsfeuV9KIg9gVLkCHIPj6FHW5Q9AvpOoGZO3h";
final JwtTokenValidator validator = new JwtTokenValidator(key);
Assertions.assertThatThrownBy(() -> validator.verifyToken(removeSignature(generateToken(key))))
.isInstanceOf(TokenVerificationException.class)
.hasMessageContaining("Token format/configuration is not supported");
}

private String removeSignature(String token) {
final String header = Base64.getEncoder()
.encodeToString("{\"alg\": \"none\"}"
.getBytes(StandardCharsets.UTF_8));

return header + token.substring(token.indexOf('.'), token.lastIndexOf('.') + 1);
}

@NotNull
private static String generateToken(String signingKey) {
return IndexerJwtAuthTokenProvider.createToken(signingKey.getBytes(StandardCharsets.UTF_8), Duration.seconds(180));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import io.jsonwebtoken.security.Keys;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Provider;
Expand Down Expand Up @@ -61,24 +63,21 @@ public IndexerJwtAuthTokenProvider(@Named("password_secret") String signingKey,
}

public static String createToken(final byte[] apiKeySecretBytes, final Duration tokenExpirationDuration) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
final SecretKey signingKey = Keys.hmacShaKeyFor(apiKeySecretBytes);

Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

JwtBuilder builder = Jwts.builder().setId("graylog datanode connect " + nowMillis)
.addClaims(Map.of("os_roles", "admin"))
.setIssuedAt(now)
.setSubject("admin")
.setIssuer("graylog")
.setNotBefore(now)
.setExpiration(new Date(nowMillis + tokenExpirationDuration.toMilliseconds()))
.signWith(signingKey, signatureAlgorithm);
JwtBuilder builder = Jwts.builder()
.id("graylog datanode connect " + nowMillis)
.claims(Map.of("os_roles", "admin"))
.issuedAt(now)
.subject("admin")
.issuer("graylog")
.notBefore(now)
.expiration(new Date(nowMillis + tokenExpirationDuration.toMilliseconds()))
.signWith(signingKey);

final var token = builder.compact();
return token;
return builder.compact();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ private ContainerizedGraylogBackend create(Services services,
}

private void createLicenses(final MongoDBInstance mongoDBInstance, final String... licenseStrs) {
final List<String> licenses = Arrays.stream(licenseStrs).map(System::getenv).filter(StringUtils::isNotBlank).collect(Collectors.toList());
final List<String> licenses = Arrays.stream(licenseStrs)
.map(System::getenv)
.filter(StringUtils::isNotBlank)
.map(String::trim)
.collect(Collectors.toList());
if (!licenses.isEmpty()) {
ServiceLoader<TestLicenseImporter> loader = ServiceLoader.load(TestLicenseImporter.class);
loader.forEach(importer -> importer.importLicenses(mongoDBInstance, licenses));
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
<zstd.version>1.5.5-11</zstd.version>
<cron-utils.version>9.2.1</cron-utils.version>
<asciitable.version>0.3.2</asciitable.version>
<jjwt.version>0.11.5</jjwt.version>
<jjwt.version>0.12.5</jjwt.version>
<stateless4j.version>2.6.0</stateless4j.version>

<!-- Test dependencies -->
Expand Down

0 comments on commit 54ff42b

Please sign in to comment.