Decode Keycloak JWTs as UTF-8 Prior to this, JWTs from Keycloak was decoded using the platform default encoding. At least in the Docker container, this is set to a non UTF-8 encoding, which messes with names and potentially more. RFC 7519 specifies in 7.1 section that the message is "the UTF-8 representation of the JWT Claims Set", so it seems rather silly to not treat it as such. Change-Id: I2dceaa48360024eef42b5467e2cec7e57c094267
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/KeycloakOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/KeycloakOAuthService.java index 34f3f87..42ff7c4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/KeycloakOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/KeycloakOAuthService.java
@@ -35,7 +35,9 @@ import com.google.inject.Provider; import com.google.inject.ProvisionException; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.concurrent.ExecutionException; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; @@ -73,11 +75,11 @@ .build(new KeycloakApi(rootUrl, realm)); } - private String parseJwt(String input) { + private String parseJwt(String input) throws UnsupportedEncodingException { String[] parts = input.split("\\."); Preconditions.checkState(parts.length == 3); Preconditions.checkNotNull(parts[1]); - return new String(Base64.decodeBase64(parts[1])); + return new String(Base64.decodeBase64(parts[1]), StandardCharsets.UTF_8.name()); } @Override @@ -85,9 +87,17 @@ JsonElement tokenJson = JSON.newGson().fromJson(token.getRaw(), JsonElement.class); JsonObject tokenObject = tokenJson.getAsJsonObject(); JsonElement id_token = tokenObject.get("id_token"); + String jwt; + try { + jwt = parseJwt(id_token.getAsString()); + } catch (UnsupportedEncodingException e) { + throw new IOException( + String.format( + "%s support is required to interact with JWTs", StandardCharsets.UTF_8.name()), + e); + } - JsonElement claimJson = - JSON.newGson().fromJson(parseJwt(id_token.getAsString()), JsonElement.class); + JsonElement claimJson = JSON.newGson().fromJson(jwt, JsonElement.class); JsonObject claimObject = claimJson.getAsJsonObject(); if (log.isDebugEnabled()) {