From 524285ba94100f996ac3a908a1c6c39f4122d9ef Mon Sep 17 00:00:00 2001 From: Andras Salamon Date: Thu, 21 Jan 2021 14:02:23 +0100 Subject: [PATCH] SOLR-15111 Use JDK8 Base64 instead of own implementation --- solr/CHANGES.txt | 2 + .../handler/admin/LukeRequestHandler.java | 6 +- .../component/TermVectorComponent.java | 6 +- .../org/apache/solr/schema/BinaryField.java | 9 +- .../org/apache/solr/schema/FieldType.java | 8 +- .../solr/schema/JsonPreAnalyzedParser.java | 12 +- .../org/apache/solr/search/CursorMark.java | 6 +- .../apache/solr/security/JWTAuthPlugin.java | 4 +- .../security/PKIAuthenticationPlugin.java | 6 +- .../java/org/apache/solr/util/CryptoKeys.java | 14 +- .../handler/component/StatsComponentTest.java | 7 +- .../security/BasicAuthStandaloneTest.java | 4 +- .../JWTAuthPluginIntegrationTest.java | 6 +- .../solr/security/JWTAuthPluginTest.java | 4 +- .../client/solrj/cloud/VersionedData.java | 4 +- .../client/solrj/impl/Http2SolrClient.java | 4 +- .../client/solrj/impl/HttpSolrClient.java | 4 +- .../solr/client/solrj/util/ClientUtils.java | 7 +- .../org/apache/solr/common/util/Base64.java | 157 ------------------ .../apache/solr/common/util/TextWriter.java | 5 +- .../solrj/impl/Http2SolrClientTest.java | 8 +- .../solr/cloud/SolrCloudAuthTestCase.java | 4 +- 22 files changed, 73 insertions(+), 214 deletions(-) delete mode 100644 solr/solrj/src/java/org/apache/solr/common/util/Base64.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index c7c9137145d..4e66153d770 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -437,6 +437,8 @@ Other Changes * SOLR-15324: Upgrade Jaeger dependency from 1.1.0 to 1.6.0 and thus also libthrift to 0.14.1 (janhoy) +* SOLR-15111: Use JDK8 Base64 instead of own implementation (Andras Salamon via janhoy) + ================== 8.9.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. diff --git a/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java index 6c8a170df82..7f6f8cb32d2 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java @@ -22,9 +22,12 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.nio.file.NoSuchFileException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; @@ -66,7 +69,6 @@ import org.apache.solr.common.luke.FieldFlag; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.SolrParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.RequestHandlerBase; @@ -294,7 +296,7 @@ private static SimpleOrderedMap getDocumentFieldsInfo( Document doc, int BytesRef bytes = field.binaryValue(); if (bytes != null) { - f.add( "binary", Base64.byteArrayToBase64(bytes.bytes, bytes.offset, bytes.length)); + f.add( "binary", new String(Base64.getEncoder().encode(ByteBuffer.wrap(bytes.bytes, bytes.offset, bytes.length)).array(), StandardCharsets.ISO_8859_1)); } if (!ftype.isPointField()) { Term t = new Term(field.name(), ftype!=null ? ftype.storedToIndexed(field) : field.stringValue()); diff --git a/solr/core/src/java/org/apache/solr/handler/component/TermVectorComponent.java b/solr/core/src/java/org/apache/solr/handler/component/TermVectorComponent.java index d25f5da790d..0269869ce67 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/TermVectorComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/TermVectorComponent.java @@ -18,8 +18,11 @@ import java.io.IOException; import java.lang.reflect.Array; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -40,7 +43,6 @@ import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.TermVectorParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.NamedList; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; @@ -364,7 +366,7 @@ private void mapOneVector(NamedList docNL, FieldOptions fieldOptions, In thePayloads = new NamedList<>(); termInfo.add("payloads", thePayloads); } - thePayloads.add("payload", Base64.byteArrayToBase64(payload.bytes, payload.offset, payload.length)); + thePayloads.add("payload", new String(Base64.getEncoder().encode(ByteBuffer.wrap(payload.bytes, payload.offset, payload.length)).array(), StandardCharsets.ISO_8859_1)); } } } diff --git a/solr/core/src/java/org/apache/solr/schema/BinaryField.java b/solr/core/src/java/org/apache/solr/schema/BinaryField.java index caeb0a30525..5aceb31f958 100644 --- a/solr/core/src/java/org/apache/solr/schema/BinaryField.java +++ b/solr/core/src/java/org/apache/solr/schema/BinaryField.java @@ -19,12 +19,13 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.SortField; import org.apache.lucene.util.BytesRef; import org.apache.solr.common.SolrException; -import org.apache.solr.common.util.Base64; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.uninverting.UninvertingReader.Type; import org.slf4j.Logger; @@ -44,7 +45,7 @@ public void checkSchemaField(SchemaField field) { } private String toBase64String(ByteBuffer buf) { - return Base64.byteArrayToBase64(buf.array(), buf.arrayOffset() + buf.position(), buf.limit()-buf.position()); + return new String(Base64.getEncoder().encode(ByteBuffer.wrap(buf.array(), buf.arrayOffset() + buf.position(), buf.limit()-buf.position()).array()), StandardCharsets.ISO_8859_1); } @Override @@ -98,7 +99,7 @@ public IndexableField createField(SchemaField field, Object val) { } else { String strVal = val.toString(); //the string has to be a base64 encoded string - buf = Base64.base64ToByteArray(strVal); + buf = Base64.getDecoder().decode(strVal); offset = 0; len = buf.length; } @@ -112,7 +113,7 @@ public Object toNativeType(Object val) { return ByteBuffer.wrap((byte[]) val); } else if (val instanceof CharSequence) { final CharSequence valAsCharSequence = (CharSequence) val; - return ByteBuffer.wrap(Base64.base64ToByteArray(valAsCharSequence.toString())); + return ByteBuffer.wrap(Base64.getDecoder().decode(valAsCharSequence.toString())); } return super.toNativeType(val); } diff --git a/solr/core/src/java/org/apache/solr/schema/FieldType.java b/solr/core/src/java/org/apache/solr/schema/FieldType.java index 7f53479f9bf..f3e995c3966 100644 --- a/solr/core/src/java/org/apache/solr/schema/FieldType.java +++ b/solr/core/src/java/org/apache/solr/schema/FieldType.java @@ -18,7 +18,10 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -67,7 +70,6 @@ import org.apache.solr.common.IteratorWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.StrUtils; import org.apache.solr.query.SolrRangeQuery; @@ -1327,7 +1329,7 @@ protected static Object marshalBase64SortValue(Object value) { return null; } final BytesRef val = (BytesRef)value; - return Base64.byteArrayToBase64(val.bytes, val.offset, val.length); + return new String(Base64.getEncoder().encode(ByteBuffer.wrap(val.bytes, val.offset, val.length)).array(), StandardCharsets.ISO_8859_1); } /** @@ -1338,7 +1340,7 @@ protected static Object unmarshalBase64SortValue(Object value) { return null; } final String val = (String)value; - final byte[] bytes = Base64.base64ToByteArray(val); + final byte[] bytes = Base64.getDecoder().decode(val); return new BytesRef(bytes); } diff --git a/solr/core/src/java/org/apache/solr/schema/JsonPreAnalyzedParser.java b/solr/core/src/java/org/apache/solr/schema/JsonPreAnalyzedParser.java index 15a3255f315..2c68adbdc61 100644 --- a/solr/core/src/java/org/apache/solr/schema/JsonPreAnalyzedParser.java +++ b/solr/core/src/java/org/apache/solr/schema/JsonPreAnalyzedParser.java @@ -19,6 +19,9 @@ import java.io.IOException; import java.io.Reader; import java.lang.invoke.MethodHandles; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; @@ -40,7 +43,6 @@ import org.apache.lucene.util.AttributeSource; import org.apache.lucene.util.AttributeSource.State; import org.apache.lucene.util.BytesRef; -import org.apache.solr.common.util.Base64; import org.apache.solr.schema.PreAnalyzedField.ParseResult; import org.apache.solr.schema.PreAnalyzedField.PreAnalyzedParser; import org.noggit.JSONUtil; @@ -100,7 +102,7 @@ public ParseResult parse(Reader reader, AttributeSource parent) res.str = (String)map.get(STRING_KEY); String bin = (String)map.get(BINARY_KEY); if (bin != null) { - byte[] data = Base64.base64ToByteArray(bin); + byte[] data = Base64.getDecoder().decode(bin); res.bin = data; } List tokens = (List)map.get(TOKENS_KEY); @@ -166,7 +168,7 @@ public ParseResult parse(Reader reader, AttributeSource parent) } else if (key.equals(PAYLOAD_KEY)) { String str = String.valueOf(e.getValue()); if (str.length() > 0) { - byte[] data = Base64.base64ToByteArray(str); + byte[] data = Base64.getDecoder().decode(str); PayloadAttribute p = parent.addAttribute(PayloadAttribute.class); if (data != null && data.length > 0) { p.setPayload(new BytesRef(data)); @@ -216,7 +218,7 @@ public String toFormattedString(Field f) throws IOException { } BytesRef binaryValue = f.binaryValue(); if (binaryValue != null) { - map.put(BINARY_KEY, Base64.byteArrayToBase64(binaryValue.bytes, binaryValue.offset, binaryValue.length)); + map.put(BINARY_KEY, new String(Base64.getEncoder().encode(ByteBuffer.wrap(binaryValue.bytes, binaryValue.offset, binaryValue.length)).array(), StandardCharsets.ISO_8859_1)); } } TokenStream ts = f.tokenStreamValue(); @@ -248,7 +250,7 @@ public String toFormattedString(Field f) throws IOException { } else if (cl.isAssignableFrom(PayloadAttribute.class)) { BytesRef p = ((PayloadAttribute)att).getPayload(); if (p != null && p.length > 0) { - tok.put(PAYLOAD_KEY, Base64.byteArrayToBase64(p.bytes, p.offset, p.length)); + tok.put(PAYLOAD_KEY, new String(Base64.getEncoder().encode(ByteBuffer.wrap(p.bytes, p.offset, p.length)).array(), StandardCharsets.ISO_8859_1)); } } else if (cl.isAssignableFrom(PositionIncrementAttribute.class)) { tok.put(POSINCR_KEY, ((PositionIncrementAttribute)att).getPositionIncrement()); diff --git a/solr/core/src/java/org/apache/solr/search/CursorMark.java b/solr/core/src/java/org/apache/solr/search/CursorMark.java index eb33b40b745..9eb92172df3 100644 --- a/solr/core/src/java/org/apache/solr/search/CursorMark.java +++ b/solr/core/src/java/org/apache/solr/search/CursorMark.java @@ -26,12 +26,12 @@ import static org.apache.solr.common.params.CursorMarkParams.*; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.JavaBinCodec; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.SchemaField; +import java.util.Base64; import java.util.List; import java.util.ArrayList; import java.io.ByteArrayOutputStream; @@ -188,7 +188,7 @@ public void parseSerializedTotem(final String serialized) { List pieces = null; try { - final byte[] rawData = Base64.base64ToByteArray(serialized); + final byte[] rawData = Base64.getDecoder().decode(serialized); try (JavaBinCodec jbc = new JavaBinCodec(); ByteArrayInputStream in = new ByteArrayInputStream(rawData)){ pieces = (List) jbc.unmarshal(in); boolean b = false; @@ -265,7 +265,7 @@ public String getSerializedTotem() { try (JavaBinCodec jbc = new JavaBinCodec(); ByteArrayOutputStream out = new ByteArrayOutputStream(256)) { jbc.marshal(marshalledValues, out); byte[] rawData = out.toByteArray(); - return Base64.byteArrayToBase64(rawData, 0, rawData.length); + return Base64.getEncoder().encodeToString(rawData); } catch (Exception ex) { throw new SolrException(ErrorCode.SERVER_ERROR, "Unable to format search after totem", ex); diff --git a/solr/core/src/java/org/apache/solr/security/JWTAuthPlugin.java b/solr/core/src/java/org/apache/solr/security/JWTAuthPlugin.java index dec6a1edd1d..c10447df0b5 100644 --- a/solr/core/src/java/org/apache/solr/security/JWTAuthPlugin.java +++ b/solr/core/src/java/org/apache/solr/security/JWTAuthPlugin.java @@ -26,7 +26,6 @@ import org.apache.solr.common.SolrException; import org.apache.solr.common.SpecProvider; import org.apache.solr.common.StringUtils; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.CommandOperation; import org.apache.solr.common.util.Utils; import org.apache.solr.common.util.ValidatingJsonMap; @@ -61,6 +60,7 @@ import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -625,7 +625,7 @@ protected String generateAuthDataHeader() { data.put("scope", adminUiScope); data.put("redirect_uris", redirectUris); String headerJson = Utils.toJSONString(data); - return Base64.byteArrayToBase64(headerJson.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(headerJson.getBytes(StandardCharsets.UTF_8)); } /** diff --git a/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java index 737706f3c29..5ec1d55516b 100644 --- a/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java +++ b/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java @@ -24,6 +24,7 @@ import java.nio.ByteBuffer; import java.security.Principal; import java.security.PublicKey; +import java.util.Base64; import java.util.List; import java.util.Map; import java.util.Optional; @@ -43,7 +44,6 @@ import org.apache.solr.client.solrj.impl.HttpClientUtil; import org.apache.solr.client.solrj.impl.HttpListenerFactory; import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.SuppressForbidden; @@ -180,7 +180,7 @@ private PKIHeaderData decipherHeader(String nodeName, String cipherBase64) { private static PKIHeaderData parseCipher(String cipher, PublicKey key) { byte[] bytes; try { - bytes = CryptoKeys.decryptRSA(Base64.base64ToByteArray(cipher), key); + bytes = CryptoKeys.decryptRSA(Base64.getDecoder().decode(cipher), key); } catch (Exception e) { log.error("Decryption failed , key must be wrong", e); return null; @@ -322,7 +322,7 @@ private Optional generateToken() { byte[] payload = s.getBytes(UTF_8); byte[] payloadCipher = publicKeyHandler.keyPair.encrypt(ByteBuffer.wrap(payload)); - String base64Cipher = Base64.byteArrayToBase64(payloadCipher); + String base64Cipher = Base64.getEncoder().encodeToString(payloadCipher); log.trace("generateToken: usr={} token={}", usr, base64Cipher); return Optional.of(base64Cipher); } diff --git a/solr/core/src/java/org/apache/solr/util/CryptoKeys.java b/solr/core/src/java/org/apache/solr/util/CryptoKeys.java index 8ec507d4868..c43feff8334 100644 --- a/solr/core/src/java/org/apache/solr/util/CryptoKeys.java +++ b/solr/core/src/java/org/apache/solr/util/CryptoKeys.java @@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableMap; import org.apache.solr.common.SolrException; -import org.apache.solr.common.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +45,7 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -77,7 +77,7 @@ public String verify(String sig, ByteBuffer data) { for (Map.Entry entry : keys.entrySet()) { boolean verified; try { - verified = CryptoKeys.verify(entry.getValue(), Base64.base64ToByteArray(sig), data); + verified = CryptoKeys.verify(entry.getValue(), Base64.getDecoder().decode(sig), data); log.debug("verified {} ", verified); if (verified) return entry.getKey(); } catch (Exception e) { @@ -95,7 +95,7 @@ public String verify(String sig, InputStream is) { for (Map.Entry entry : keys.entrySet()) { boolean verified; try { - verified = CryptoKeys.verify(entry.getValue(), Base64.base64ToByteArray(sig), is); + verified = CryptoKeys.verify(entry.getValue(), Base64.getDecoder().decode(sig), is); log.debug("verified {} ", verified); if (verified) return entry.getKey(); } catch (Exception e) { @@ -172,7 +172,7 @@ public static boolean verify(PublicKey publicKey, byte[] sig, InputStream is) public static PublicKey deserializeX509PublicKey(String pubKey) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.base64ToByteArray(pubKey)); + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(pubKey)); return keyFactory.generatePublic(publicKeySpec); } catch (Exception e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,e); @@ -247,7 +247,7 @@ public RSAKeyPair() { java.security.KeyPair keyPair = keyGen.genKeyPair(); privateKey = keyPair.getPrivate(); publicKey = keyPair.getPublic(); - pubKeyStr = Base64.byteArrayToBase64(publicKey.getEncoded()); + pubKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded()); } /** @@ -263,7 +263,7 @@ public RSAKeyPair(URL privateKeyResourceName, URL publicKeyResourceName) throws String privateString = new String(inPrivate.readAllBytes(), StandardCharsets.UTF_8) .replaceAll("-----(BEGIN|END) PRIVATE KEY-----", ""); - PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(java.util.Base64.getMimeDecoder().decode(privateString)); + PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(privateString)); KeyFactory rsaFactory = KeyFactory.getInstance("RSA"); privateKey = rsaFactory.generatePrivate(privateSpec); } catch (NoSuchAlgorithmException e) { @@ -272,7 +272,7 @@ public RSAKeyPair(URL privateKeyResourceName, URL publicKeyResourceName) throws try (InputStream inPublic = publicKeyResourceName.openStream()) { publicKey = getX509PublicKey(inPublic.readAllBytes()); - pubKeyStr = Base64.byteArrayToBase64(publicKey.getEncoded()); + pubKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded()); } } diff --git a/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java index b1636d1cc04..41eea09ec5e 100644 --- a/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java +++ b/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java @@ -16,10 +16,12 @@ */ package org.apache.solr.handler.component; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.Date; import java.util.EnumSet; @@ -44,7 +46,6 @@ import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.StatsParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.StrUtils; import org.apache.solr.core.SolrCore; @@ -1410,7 +1411,7 @@ public void testIndividualStatLocalParams() throws Exception { Collections.singletonList(distinctValsXpath)); ExpectedStat.createSimple(Stat.countDistinct, "true", "long", "10"); final String percentileShardXpath = kpre + "str[@name='percentiles'][.='" - + Base64.byteArrayToBase64(tdigestBuf.array(), 0, tdigestBuf.array().length) + "']"; + + new String(Base64.getEncoder().encode(tdigestBuf.array()), StandardCharsets.ISO_8859_1) + "']"; final String p90 = "" + tdigest.quantile(0.90D); final String p99 = "" + tdigest.quantile(0.99D); ExpectedStat.create(Stat.percentiles, "'90, 99'", @@ -1419,7 +1420,7 @@ public void testIndividualStatLocalParams() throws Exception { kpre + "lst[@name='percentiles']/double[@name='90.0'][.="+p90+"]", kpre + "lst[@name='percentiles']/double[@name='99.0'][.="+p99+"]")); final String cardinalityShardXpath = kpre + "str[@name='cardinality'][.='" - + Base64.byteArrayToBase64(hllBytes, 0, hllBytes.length) + "']"; + + new String(Base64.getEncoder().encode(hllBytes),StandardCharsets.ISO_8859_1) + "']"; final String cardinalityXpath = kpre + "long[@name='cardinality'][.='10']"; ExpectedStat.create(Stat.cardinality, "true", Collections.singletonList(cardinalityShardXpath), diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthStandaloneTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthStandaloneTest.java index 406ce589b6d..4f198c5cce1 100644 --- a/solr/core/src/test/org/apache/solr/security/BasicAuthStandaloneTest.java +++ b/solr/core/src/test/org/apache/solr/security/BasicAuthStandaloneTest.java @@ -22,6 +22,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Base64; import java.util.Collections; import java.util.Properties; @@ -36,7 +37,6 @@ import org.apache.solr.client.solrj.impl.HttpClientUtil; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.common.params.MapSolrParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.Utils; import org.apache.solr.handler.admin.SecurityConfHandler; import org.apache.solr.handler.admin.SecurityConfHandlerLocalForTesting; @@ -162,7 +162,7 @@ private void doHttpPost(HttpClient cl, String url, String jsonCommand, String ba public static void setBasicAuthHeader(AbstractHttpMessage httpMsg, String user, String pwd) { String userPass = user + ":" + pwd; - String encoded = Base64.byteArrayToBase64(userPass.getBytes(UTF_8)); + String encoded = Base64.getEncoder().encodeToString(userPass.getBytes(UTF_8)); httpMsg.setHeader(new BasicHeader("Authorization", "Basic " + encoded)); log.info("Added Basic Auth security Header {}",encoded ); } diff --git a/solr/core/src/test/org/apache/solr/security/JWTAuthPluginIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/JWTAuthPluginIntegrationTest.java index d6b99ef1a78..c7bcb270510 100644 --- a/solr/core/src/test/org/apache/solr/security/JWTAuthPluginIntegrationTest.java +++ b/solr/core/src/test/org/apache/solr/security/JWTAuthPluginIntegrationTest.java @@ -35,7 +35,6 @@ import org.apache.solr.cloud.MiniSolrCloudCluster; import org.apache.solr.cloud.SolrCloudAuthTestCase; import org.apache.solr.common.SolrException; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.Pair; import org.apache.solr.common.util.TimeSource; import org.apache.solr.common.util.Utils; @@ -69,6 +68,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.security.KeyStore; +import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -159,7 +159,7 @@ public void testStaticJwtKeys() throws Exception { Map headers = getHeaders(baseUrl + "/admin/info/system", null); assertEquals("Should have received 401 code", "401", headers.get("code")); assertEquals("Bearer realm=\"my-solr-jwt\"", headers.get("WWW-Authenticate")); - String authData = new String(Base64.base64ToByteArray(headers.get("X-Solr-AuthData")), UTF_8); + String authData = new String(Base64.getDecoder().decode(headers.get("X-Solr-AuthData")), UTF_8); assertEquals("{\n" + " \"scope\":\"solr:admin\",\n" + " \"redirect_uris\":[],\n" + @@ -177,7 +177,7 @@ public void infoRequestValidateXSolrAuthHeadersBlockUnknownFalse() throws Except Map headers = getHeaders(baseUrl + "/admin/info/system", null); assertEquals("Should have received 401 code", "401", headers.get("code")); assertEquals("Bearer realm=\"my-solr-jwt-blockunknown-false\"", headers.get("WWW-Authenticate")); - String authData = new String(Base64.base64ToByteArray(headers.get("X-Solr-AuthData")), UTF_8); + String authData = new String(Base64.getDecoder().decode(headers.get("X-Solr-AuthData")), UTF_8); assertEquals("{\n" + " \"scope\":\"solr:admin\",\n" + " \"redirect_uris\":[],\n" + diff --git a/solr/core/src/test/org/apache/solr/security/JWTAuthPluginTest.java b/solr/core/src/test/org/apache/solr/security/JWTAuthPluginTest.java index f9054bc089b..a58c9b7fcb8 100644 --- a/solr/core/src/test/org/apache/solr/security/JWTAuthPluginTest.java +++ b/solr/core/src/test/org/apache/solr/security/JWTAuthPluginTest.java @@ -19,7 +19,6 @@ import org.apache.commons.io.IOUtils; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrException; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.Utils; import org.apache.solr.util.CryptoKeys; import org.jose4j.jwk.RsaJsonWebKey; @@ -43,6 +42,7 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -437,7 +437,7 @@ public void xSolrAuthDataHeader() { testConfig.put("clientId", "solr-cluster"); plugin.init(testConfig); String headerBase64 = plugin.generateAuthDataHeader(); - String headerJson = new String(Base64.base64ToByteArray(headerBase64), StandardCharsets.UTF_8); + String headerJson = new String(Base64.getDecoder().decode(headerBase64), StandardCharsets.UTF_8); Map parsed = (Map) Utils.fromJSONString(headerJson); assertEquals("solr:admin", parsed.get("scope")); assertEquals("http://acmepaymentscorp/oauth/auz/authorize", parsed.get("authorizationEndpoint")); diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java b/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java index 711411d4a24..003bb83b29d 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java @@ -18,10 +18,10 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Base64; import java.util.Objects; import org.apache.solr.common.MapWriter; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.Utils; import org.apache.zookeeper.CreateMode; @@ -72,7 +72,7 @@ public void writeMap(EntryWriter ew) throws IOException { } ew.put("mode", mode.toString()); if (data != null) { - ew.put("data", Base64.byteArrayToBase64(data)); + ew.put("data", Base64.getEncoder().encodeToString(data)); } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java index d51114754d8..768cb1fae80 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java @@ -28,6 +28,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -65,7 +66,6 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.UpdateParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.NamedList; @@ -488,7 +488,7 @@ private void setBasicAuthHeader(SolrRequest solrRequest, Request req) { private String basicAuthCredentialsToAuthorizationString(String user, String pass) { String userPass = user + ":" + pass; - return "Basic " + Base64.byteArrayToBase64(userPass.getBytes(FALLBACK_CHARSET)); + return "Basic " + Base64.getEncoder().encodeToString(userPass.getBytes(FALLBACK_CHARSET)); } private Request makeRequest(SolrRequest solrRequest, String collection) diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java index 4c33d05c69c..93bb8bb7796 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java @@ -29,6 +29,7 @@ import java.nio.charset.StandardCharsets; import java.security.Principal; import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -79,7 +80,6 @@ import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.NamedList; @@ -275,7 +275,7 @@ private boolean isV2ApiRequest(final SolrRequest request) { private void setBasicAuthHeader(SolrRequest request, HttpRequestBase method) throws UnsupportedEncodingException { if (request.getBasicAuthUser() != null && request.getBasicAuthPassword() != null) { String userPass = request.getBasicAuthUser() + ":" + request.getBasicAuthPassword(); - String encoded = Base64.byteArrayToBase64(userPass.getBytes(FALLBACK_CHARSET)); + String encoded = Base64.getEncoder().encodeToString(userPass.getBytes(FALLBACK_CHARSET)); method.setHeader(new BasicHeader("Authorization", "Basic " + encoded)); } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java b/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java index b96a8cb990d..314b5a62454 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java @@ -20,7 +20,9 @@ import java.io.StringWriter; import java.io.Writer; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Date; import java.util.Map; @@ -29,7 +31,6 @@ import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.SolrInputField; import org.apache.solr.common.cloud.Slice; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ContentStreamBase; import org.apache.solr.common.util.XML; @@ -110,10 +111,10 @@ private static void writeVal(Writer writer, String name, Object v, String update v = ((Date)v).toInstant().toString(); } else if (v instanceof byte[]) { byte[] bytes = (byte[]) v; - v = Base64.byteArrayToBase64(bytes, 0, bytes.length); + v = Base64.getEncoder().encodeToString(bytes); } else if (v instanceof ByteBuffer) { ByteBuffer bytes = (ByteBuffer) v; - v = Base64.byteArrayToBase64(bytes.array(), bytes.arrayOffset() + bytes.position(),bytes.limit() - bytes.position()); + v = new String(Base64.getEncoder().encode(ByteBuffer.wrap(bytes.array(), bytes.arrayOffset() + bytes.position(),bytes.limit() - bytes.position())).array(), StandardCharsets.ISO_8859_1); } XML.Writable valWriter = null; diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Base64.java b/solr/solrj/src/java/org/apache/solr/common/util/Base64.java deleted file mode 100644 index e470ed94495..00000000000 --- a/solr/solrj/src/java/org/apache/solr/common/util/Base64.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.solr.common.util; - -/** - * Static methods for translating Base64 encoded strings to byte arrays - * and vice-versa. - */ - -public class Base64 { - /** - * This array is a lookup table that translates 6-bit positive integer - * index values into their "Base64 Alphabet" equivalents as specified - * in Table 1 of RFC 2045. - */ - private static final char intToBase64[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - - /** - * This array is a lookup table that translates unicode characters - * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) - * into their 6-bit positive integer equivalents. Characters that - * are not in the Base64 alphabet but fall within the bounds of the - * array are translated to -1. - */ - private static final byte base64ToInt[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 - }; - - public static String byteArrayToBase64(byte[] a) { - return byteArrayToBase64(a, 0, a.length); - } - - public static String byteArrayToBase64(byte[] a, int offset, int len) { - int aLen = len; - int numFullGroups = aLen / 3; - int numBytesInPartialGroup = aLen - 3 * numFullGroups; - int resultLen = 4 * ((aLen + 2) / 3); - StringBuilder result = new StringBuilder(resultLen); - char[] intToAlpha = intToBase64; - - // Translate all full groups from byte array elements to Base64 - int inCursor = offset; - for (int i = 0; i < numFullGroups; i++) { - int byte0 = a[inCursor++] & 0xff; - int byte1 = a[inCursor++] & 0xff; - int byte2 = a[inCursor++] & 0xff; - result.append(intToAlpha[byte0 >> 2]); - result.append(intToAlpha[(byte0 << 4) & 0x3f | (byte1 >> 4)]); - result.append(intToAlpha[(byte1 << 2) & 0x3f | (byte2 >> 6)]); - result.append(intToAlpha[byte2 & 0x3f]); - } - - // Translate partial group if present - if (numBytesInPartialGroup != 0) { - int byte0 = a[inCursor++] & 0xff; - result.append(intToAlpha[byte0 >> 2]); - if (numBytesInPartialGroup == 1) { - result.append(intToAlpha[(byte0 << 4) & 0x3f]); - result.append("=="); - } else { - // assert numBytesInPartialGroup == 2; - int byte1 = a[inCursor++] & 0xff; - result.append(intToAlpha[(byte0 << 4) & 0x3f | (byte1 >> 4)]); - result.append(intToAlpha[(byte1 << 2) & 0x3f]); - result.append('='); - } - } - return result.toString(); - } - - public static byte[] base64ToByteArray(String s) { - byte[] alphaToInt = base64ToInt; - int sLen = s.length(); - int numGroups = sLen / 4; - if (4 * numGroups != sLen) - throw new IllegalArgumentException( - "String length must be a multiple of four."); - int missingBytesInLastGroup = 0; - int numFullGroups = numGroups; - if (sLen != 0) { - if (s.charAt(sLen - 1) == '=') { - missingBytesInLastGroup++; - numFullGroups--; - } - if (s.charAt(sLen - 2) == '=') - missingBytesInLastGroup++; - } - byte[] result = new byte[3 * numGroups - missingBytesInLastGroup]; - - // Translate all full groups from base64 to byte array elements - int inCursor = 0, outCursor = 0; - for (int i = 0; i < numFullGroups; i++) { - int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); - result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); - result[outCursor++] = (byte) ((ch2 << 6) | ch3); - } - - // Translate partial group, if present - if (missingBytesInLastGroup != 0) { - int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); - int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); - - if (missingBytesInLastGroup == 1) { - int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); - result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); - } - } - // assert inCursor == s.length()-missingBytesInLastGroup; - // assert outCursor == result.length; - return result; - } - - /** - * Translates the specified character, which is assumed to be in the - * "Base 64 Alphabet" into its equivalent 6-bit positive integer. - * - * @throw IllegalArgumentException or ArrayOutOfBoundsException if - * c is not in the Base64 Alphabet. - */ - private static int base64toInt(char c, byte[] alphaToInt) { - int result = alphaToInt[c]; - if (result < 0) - throw new IllegalArgumentException("Illegal character " + c); - return result; - } -} diff --git a/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java b/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java index 85bd5b76052..e02677fbd5b 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java @@ -19,8 +19,11 @@ import java.io.IOException; import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Arrays; +import java.util.Base64; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; @@ -164,7 +167,7 @@ default void writeDate(String name, Date val) throws IOException { } default void writeByteArr(String name, byte[] buf, int offset, int len) throws IOException { - writeStr(name, Base64.byteArrayToBase64(buf, offset, len), false); + writeStr(name, new String(Base64.getEncoder().encode(ByteBuffer.wrap(buf, offset, len)).array(), StandardCharsets.ISO_8859_1), false); } default void writeInt(String name, int val) throws IOException { diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java index 71a059995e0..059cd07a7e2 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java @@ -29,7 +29,6 @@ import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.MapSolrParams; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.SuppressForbidden; import org.eclipse.jetty.client.WWWAuthenticationProtocolHandler; import org.eclipse.jetty.http.HttpStatus; @@ -41,6 +40,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; @@ -674,7 +674,7 @@ public void testSetCredentialsExplicitly() { assertTrue(DebugServlet.headers.size() > 0); String authorizationHeader = DebugServlet.headers.get("authorization"); assertNotNull("No authorization information in headers found. Headers: " + DebugServlet.headers, authorizationHeader); - assertEquals("Basic " + Base64.byteArrayToBase64("foo:explicit".getBytes(StandardCharsets.UTF_8)), authorizationHeader); + assertEquals("Basic " + Base64.getEncoder().encodeToString("foo:explicit".getBytes(StandardCharsets.UTF_8)), authorizationHeader); } } @@ -696,7 +696,7 @@ public void testSetCredentialsWithSysProps() throws IOException, SolrServerExcep assertTrue(DebugServlet.headers.size() > 0); String authorizationHeader = DebugServlet.headers.get("authorization"); assertNotNull("No authorization information in headers found. Headers: " + DebugServlet.headers, authorizationHeader); - assertEquals("Basic " + Base64.byteArrayToBase64("foo:bar".getBytes(StandardCharsets.UTF_8)), authorizationHeader); + assertEquals("Basic " + Base64.getEncoder().encodeToString("foo:bar".getBytes(StandardCharsets.UTF_8)), authorizationHeader); } finally { System.clearProperty(PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_BASIC_AUTH_CREDENTIALS); System.clearProperty(HttpClientUtil.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY); @@ -720,7 +720,7 @@ public void testPerRequestCredentialsWin() { assertTrue(DebugServlet.headers.size() > 0); String authorizationHeader = DebugServlet.headers.get("authorization"); assertNotNull("No authorization information in headers found. Headers: " + DebugServlet.headers, authorizationHeader); - assertEquals("Basic " + Base64.byteArrayToBase64("foo3:per-request".getBytes(StandardCharsets.UTF_8)), authorizationHeader); + assertEquals("Basic " + Base64.getEncoder().encodeToString("foo3:per-request".getBytes(StandardCharsets.UTF_8)), authorizationHeader); } finally { System.clearProperty("basicauth"); } diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudAuthTestCase.java b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudAuthTestCase.java index 462e2abb210..f9185622bf6 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudAuthTestCase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudAuthTestCase.java @@ -21,6 +21,7 @@ import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -40,7 +41,6 @@ import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; import org.apache.solr.client.solrj.embedded.JettySolrRunner; -import org.apache.solr.common.util.Base64; import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.Utils; import org.apache.solr.util.TimeOut; @@ -239,7 +239,7 @@ private static void verifySecurityStatus(HttpClient cl, String url, String objPa protected static String makeBasicAuthHeader(String user, String pwd) { String userPass = user + ":" + pwd; - return "Basic " + Base64.byteArrayToBase64(userPass.getBytes(UTF_8)); + return "Basic " + Base64.getEncoder().encodeToString(userPass.getBytes(UTF_8)); } static String getBearerAuthHeader(JsonWebSignature jws) throws JoseException {