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()) {