From 230389271259d7d6a322b1357f41087d1cf27272 Mon Sep 17 00:00:00 2001 From: Zixuan Liu Date: Thu, 4 Aug 2022 15:21:30 +0800 Subject: [PATCH] [improve][authentication] Adapt basic authentication configuration with prefix (#16935) Signed-off-by: Zixuan Liu (cherry picked from commit cd95594f086dd6474962e21b24cd5c27fca3933f) (cherry picked from commit 0a4add693b5c7164098ff24ae33feb585aaf40bf) --- .../AuthenticationProviderBasic.java | 41 ++++++++++++------- .../AuthenticationProviderBasicTest.java | 18 +++++++- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasic.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasic.java index ff62bf60cb469..9f6bacf729891 100644 --- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasic.java +++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasic.java @@ -20,11 +20,12 @@ package org.apache.pulsar.broker.authentication; import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; +import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.HashMap; @@ -34,9 +35,11 @@ import lombok.Cleanup; import org.apache.commons.codec.digest.Crypt; import org.apache.commons.codec.digest.Md5Crypt; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.broker.authentication.metrics.AuthenticationMetrics; +import org.apache.pulsar.client.api.url.URL; public class AuthenticationProviderBasic implements AuthenticationProvider { private static final String HTTP_HEADER_NAME = "Authorization"; @@ -49,6 +52,20 @@ public void close() throws IOException { // noop } + public static byte[] readData(String data) + throws IOException, URISyntaxException, InstantiationException, IllegalAccessException { + if (data.startsWith("data:") || data.startsWith("file:")) { + return IOUtils.toByteArray(URL.createURL(data)); + } else if (Files.exists(Paths.get(data))) { + return Files.readAllBytes(Paths.get(data)); + } else if (org.apache.commons.codec.binary.Base64.isBase64(data)) { + return Base64.getDecoder().decode(data); + } else { + String msg = "Not supported config"; + throw new IllegalArgumentException(msg); + } + } + @Override public void initialize(ServiceConfiguration config) throws IOException { String data = config.getProperties().getProperty(CONF_PULSAR_PROPERTY_KEY); @@ -60,17 +77,11 @@ public void initialize(ServiceConfiguration config) throws IOException { } @Cleanup BufferedReader reader = null; - if (org.apache.commons.codec.binary.Base64.isBase64(data)) { - reader = new BufferedReader(new StringReader(new String(Base64.getDecoder().decode(data), - StandardCharsets.UTF_8))); - } else { - File confFile = new File(data); - if (!confFile.exists()) { - throw new IOException("The password auth conf file does not exist"); - } else if (!confFile.isFile()) { - throw new IOException("The path is not a file"); - } - reader = new BufferedReader(new FileReader(confFile)); + try { + byte[] bytes = readData(data); + reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes))); + } catch (Exception e) { + throw new IllegalArgumentException(e); } users = new HashMap<>(); diff --git a/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasicTest.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasicTest.java index 217d9af9e08b2..fa72af76e8a34 100644 --- a/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasicTest.java +++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderBasicTest.java @@ -18,6 +18,7 @@ */ package org.apache.pulsar.broker.authentication; +import static org.testng.Assert.assertEquals; import com.google.common.io.Resources; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -25,13 +26,12 @@ import java.nio.file.Path; import java.util.Base64; import java.util.Properties; +import javax.naming.AuthenticationException; import lombok.Cleanup; import org.apache.pulsar.broker.ServiceConfiguration; import org.apache.pulsar.common.api.AuthData; import org.testng.annotations.Test; -import javax.naming.AuthenticationException; - public class AuthenticationProviderBasicTest { private final String basicAuthConf = Resources.getResource("authentication/basic/.htpasswd").getPath(); private final String basicAuthConfBase64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Path.of(basicAuthConf))); @@ -87,4 +87,18 @@ public void testLoadBase64FromSystemProperties() throws Exception { provider.initialize(serviceConfiguration); testAuthenticate(provider); } + + @Test + public void testReadData() throws Exception { + byte[] data = Files.readAllBytes(Path.of(basicAuthConf)); + String base64Data = Base64.getEncoder().encodeToString(data); + + // base64 format + assertEquals(AuthenticationProviderBasic.readData("data:;base64," + base64Data), data); + assertEquals(AuthenticationProviderBasic.readData(base64Data), data); + + // file format + assertEquals(AuthenticationProviderBasic.readData("file://" + basicAuthConf), data); + assertEquals(AuthenticationProviderBasic.readData(basicAuthConf), data); + } }