Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
public class JsonwebtokenResolverTests {

@Test
void testResolveTokenSuccessfully(VaultEnvironment vaultEnvironment) throws Exception {
void testResolveTokenTokenSuccessfully(VaultEnvironment vaultEnvironment) throws Exception {
final var token = vaultEnvironment.newServiceToken();

final var jwtToken =
Expand All @@ -35,7 +35,7 @@ void testResolveTokenSuccessfully(VaultEnvironment vaultEnvironment) throws Exce
.requestTimeout(Duration.ofSeconds(3))
.keyTtl(1000)
.build())
.resolve(token)
.resolveToken(token)
.get(3, TimeUnit.SECONDS);

assertNotNull(jwtToken, "jwtToken");
Expand All @@ -47,15 +47,7 @@ void testResolveTokenSuccessfully(VaultEnvironment vaultEnvironment) throws Exce
void testParseTokenSuccessfully(VaultEnvironment vaultEnvironment) {
final var token = vaultEnvironment.newServiceToken();

final var jwtToken =
new JsonwebtokenResolver(
JwksKeyLocator.builder()
.jwksUri(vaultEnvironment.jwksUri())
.connectTimeout(Duration.ofSeconds(3))
.requestTimeout(Duration.ofSeconds(3))
.keyTtl(1000)
.build())
.parse(token);
final var jwtToken = JwtToken.parseToken(token);

assertNotNull(jwtToken, "jwtToken");
assertTrue(jwtToken.header().size() > 0, "jwtToken.header: " + jwtToken.header());
Expand All @@ -70,7 +62,7 @@ void testJwksKeyLocatorThrowsError(VaultEnvironment vaultEnvironment) {
when(keyLocator.locate(any())).thenThrow(new RuntimeException("Cannot get key"));

try {
new JsonwebtokenResolver(keyLocator).resolve(token).get(3, TimeUnit.SECONDS);
new JsonwebtokenResolver(keyLocator).resolveToken(token).get(3, TimeUnit.SECONDS);
fail("Expected exception");
} catch (Exception e) {
final var ex = getRootCause(e);
Expand All @@ -87,7 +79,7 @@ void testJwksKeyLocatorThrowsRetryableError(VaultEnvironment vaultEnvironment) {
when(keyLocator.locate(any())).thenThrow(new JwtUnavailableException("JWKS timeout"));

try {
new JsonwebtokenResolver(keyLocator).resolve(token).get(3, TimeUnit.SECONDS);
new JsonwebtokenResolver(keyLocator).resolveToken(token).get(3, TimeUnit.SECONDS);
fail("Expected exception");
} catch (Exception e) {
final var ex = getRootCause(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void testGetServiceTokenSuccessfully(VaultEnvironment vaultEnvironment) throws E
final var jwtToken =
new JsonwebtokenResolver(
JwksKeyLocator.builder().jwksUri(vaultEnvironment.jwksUri()).build())
.resolve(serviceToken)
.resolveToken(serviceToken)
.get(3, TimeUnit.SECONDS);

assertNotNull(jwtToken, "jwtToken");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package io.scalecube.security.tokens.jwt;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Locator;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Base64;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
Expand All @@ -24,7 +19,7 @@ public JsonwebtokenResolver(Locator<Key> keyLocator) {
}

@Override
public CompletableFuture<JwtToken> resolve(String token) {
public CompletableFuture<JwtToken> resolveToken(String token) {
return CompletableFuture.supplyAsync(
() -> {
final var claimsJws =
Expand All @@ -50,29 +45,6 @@ public CompletableFuture<JwtToken> resolve(String token) {
});
}

@Override
public JwtToken parse(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
throw new JwtTokenException("Invalid JWT format");
}

try {
final var urlDecoder = Base64.getUrlDecoder();
final var headerJson = new String(urlDecoder.decode(parts[0]), StandardCharsets.UTF_8);
final var payloadJson = new String(urlDecoder.decode(parts[1]), StandardCharsets.UTF_8);

final var mapper = new ObjectMapper();
final var header = mapper.readValue(headerJson, Map.class);
final var claims = mapper.readValue(payloadJson, Map.class);

//noinspection unchecked
return new JwtToken(header, claims);
} catch (IOException e) {
throw new JwtTokenException("Failed to decode JWT", e);
}
}

private static String mask(String data) {
if (data == null || data.length() < 5) {
return "*****";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
package io.scalecube.security.tokens.jwt;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;

public record JwtToken(Map<String, Object> header, Map<String, Object> payload) {}
public record JwtToken(Map<String, Object> header, Map<String, Object> payload) {

/**
* Parses given JWT without verifying its signature.
*
* @param token jwt token
* @return parsed token
*/
public static JwtToken parseToken(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
throw new JwtTokenException("Invalid JWT format");
}

try {
final var urlDecoder = Base64.getUrlDecoder();
final var headerJson = new String(urlDecoder.decode(parts[0]), StandardCharsets.UTF_8);
final var payloadJson = new String(urlDecoder.decode(parts[1]), StandardCharsets.UTF_8);

final var mapper = new ObjectMapper();
final var header = mapper.readValue(headerJson, Map.class);
final var claims = mapper.readValue(payloadJson, Map.class);

//noinspection unchecked
return new JwtToken(header, claims);
} catch (IOException e) {
throw new JwtTokenException("Failed to decode JWT", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,5 @@ public interface JwtTokenResolver {
* @param token jwt token
* @return async result with {@link JwtToken}, or error
*/
CompletableFuture<JwtToken> resolve(String token);

/**
* Parses given JWT without verifying its signature.
*
* @param token jwt token
* @return parsed token
*/
JwtToken parse(String token);
CompletableFuture<JwtToken> resolveToken(String token);
}