This is an automated email from the ASF dual-hosted git repository.
alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push:
new ede75bc16 [client] KUDU-3472 Java client API to import JWT
ede75bc16 is described below
commit ede75bc162c14cb58b2c5cceef6a7072c0d7428c
Author: Zoltan Chovan <[email protected]>
AuthorDate: Wed May 3 18:56:47 2023 +0200
[client] KUDU-3472 Java client API to import JWT
This patch adds one new method into AsyncKuduClient and KuduClient API
to set a JWT (JSON Web Token) to be used for authentication. The newly
introduced API matches the one introduced in the C++ Kudu client.
Change-Id: Ic43bd1219f4613e9cac11762726a5d6d2cdc764b
Reviewed-on: http://gerrit.cloudera.org:8080/19836
Tested-by: Alexey Serbin <[email protected]>
Reviewed-by: Alexey Serbin <[email protected]>
---
.../org/apache/kudu/client/AsyncKuduClient.java | 19 ++++++++++++
.../java/org/apache/kudu/client/KuduClient.java | 17 +++++++++++
.../org/apache/kudu/client/SecurityContext.java | 14 ++++++---
.../org/apache/kudu/test/TestMiniKuduCluster.java | 35 +++++++---------------
4 files changed, 57 insertions(+), 28 deletions(-)
diff --git
a/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
b/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
index 2e8a24ed2..68aa1b2fc 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
@@ -80,6 +80,7 @@ import
org.apache.kudu.master.Master.GetTableLocationsResponsePB;
import org.apache.kudu.master.Master.TSInfoPB;
import org.apache.kudu.master.Master.TableIdentifierPB;
import org.apache.kudu.master.Master.TabletLocationsPB;
+import org.apache.kudu.security.Token;
import org.apache.kudu.security.Token.SignedTokenPB;
import org.apache.kudu.util.AsyncUtil;
import org.apache.kudu.util.NetUtil;
@@ -1177,6 +1178,24 @@ public class AsyncKuduClient implements AutoCloseable {
securityContext.importAuthenticationCredentials(authnData);
}
+ /**
+ * Set JWT (JSON Web Token) to authenticate the client to a server.
+ * <p>
+ * @note If {@link #importAuthenticationCredentials(byte[] authnData)} and
+ * this method are called on the same object, the JWT provided with this call
+ * overrides the corresponding JWT that comes as a part of the imported
+ * authentication credentials (if present).
+ *
+ * @param jwt The JSON web token to set.
+ */
+ @InterfaceStability.Unstable
+ public void jwt(String jwt) {
+ Token.JwtRawPB jwtPB = Token.JwtRawPB.newBuilder()
+ .setJwtData(ByteString.copyFromUtf8(jwt))
+ .build();
+ securityContext.setJsonWebToken(jwtPB);
+ }
+
/**
* Get the timeout used for operations on sessions and scanners.
* @return a timeout in milliseconds
diff --git
a/java/kudu-client/src/main/java/org/apache/kudu/client/KuduClient.java
b/java/kudu-client/src/main/java/org/apache/kudu/client/KuduClient.java
index 1536574df..ed2f90e30 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/KuduClient.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/KuduClient.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.concurrent.Executor;
import com.google.common.base.Preconditions;
+import com.google.protobuf.ByteString;
import com.stumbleupon.async.Deferred;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;
@@ -30,6 +31,7 @@ import org.slf4j.LoggerFactory;
import org.apache.kudu.Schema;
import org.apache.kudu.master.Master.TableIdentifierPB;
+import org.apache.kudu.security.Token;
/**
* A synchronous and thread-safe client for Kudu.
@@ -466,6 +468,21 @@ public class KuduClient implements AutoCloseable {
asyncClient.importAuthenticationCredentials(authnData);
}
+ /**
+ * Set JWT (JSON Web Token) to authenticate the client to a server.
+ * <p>
+ * @note If {@link #importAuthenticationCredentials(byte[] authnData)} and
+ * this method are called on the same object, the JWT provided with this call
+ * overrides the corresponding JWT that comes as a part of the imported
+ * authentication credentials (if present).
+ *
+ * @param jwt The JSON web token to set.
+ */
+ @InterfaceStability.Unstable
+ public void jwt(String jwt) {
+ asyncClient.jwt(jwt);
+ }
+
/**
* Get the timeout used for operations on sessions and scanners.
* @return a timeout in milliseconds
diff --git
a/java/kudu-client/src/main/java/org/apache/kudu/client/SecurityContext.java
b/java/kudu-client/src/main/java/org/apache/kudu/client/SecurityContext.java
index 8597e0cd9..b02c020a4 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/SecurityContext.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/SecurityContext.java
@@ -278,6 +278,9 @@ class SecurityContext {
if (authnToken != null) {
pb.setAuthnToken(authnToken);
}
+ if (jsonWebToken != null) {
+ pb.setJwt(jsonWebToken);
+ }
pb.addAllCaCertDers(trustedCertDers);
return pb.build().toByteArray();
}
@@ -315,10 +318,9 @@ class SecurityContext {
}
LOG.debug("Importing authentication credentials with {} authn token, " +
- "JWT={} , " +
- "{} cert(s), and realUser={}",
+ "with {} JWT, {} cert(s), and realUser={}",
pb.hasAuthnToken() ? "one" : "no",
- pb.hasJwt() ? pb.getJwt() : "<none>",
+ pb.hasJwt() ? "one" : "no",
pb.getCaCertDersCount(),
pb.hasRealUser() ? pb.getRealUser() : "<none>");
if (pb.hasAuthnToken()) {
@@ -327,7 +329,11 @@ class SecurityContext {
trustCertificates(pb.getCaCertDersList());
if (pb.hasJwt()) {
- jsonWebToken = pb.getJwt();
+ // Don't overwrite the JWT in the context if it's already set.
+ if (!jsonWebToken.hasJwtData() ||
+ (jsonWebToken.hasJwtData() &&
jsonWebToken.getJwtData().isEmpty())) {
+ jsonWebToken = pb.getJwt();
+ }
}
if (pb.hasRealUser()) {
diff --git
a/java/kudu-test-utils/src/test/java/org/apache/kudu/test/TestMiniKuduCluster.java
b/java/kudu-test-utils/src/test/java/org/apache/kudu/test/TestMiniKuduCluster.java
index ddfbe6d9b..c31efb399 100644
---
a/java/kudu-test-utils/src/test/java/org/apache/kudu/test/TestMiniKuduCluster.java
+++
b/java/kudu-test-utils/src/test/java/org/apache/kudu/test/TestMiniKuduCluster.java
@@ -119,31 +119,18 @@ public class TestMiniKuduCluster {
@Test(timeout = 50000)
public void testJwt() throws Exception {
- try {
- MiniKuduClusterBuilder clusterBuilder = new
MiniKuduCluster.MiniKuduClusterBuilder()
- .numMasterServers(NUM_MASTERS)
- .numTabletServers(0)
- .enableClientJwt()
- .addJwks("account-id", true);
-
- harness = new KuduTestHarness(clusterBuilder);
- harness.before();
- harness.startAllMasterServers();
-
- String jwt = harness.createJwtFor("account-id", "subject", true);
+ try (MiniKuduCluster cluster = new MiniKuduCluster.MiniKuduClusterBuilder()
+
.numMasterServers(NUM_MASTERS)
+ .numTabletServers(0)
+ .enableClientJwt()
+ .addJwks("account-id",
true)
+ .build();
+ KuduClient client = new
KuduClientBuilder(cluster.getMasterAddressesAsString()).build()) {
+ String jwt = cluster.createJwtFor("account-id", "subject", true);
assertNotNull(jwt);
- AuthenticationCredentialsPB credentials =
AuthenticationCredentialsPB.newBuilder()
- .setJwt(JwtRawPB.newBuilder()
- .setJwtData(ByteString.copyFromUtf8(jwt))
- .build())
- .build();
-
- AsyncKuduClient c = harness.getAsyncClient();
- c.importAuthenticationCredentials(credentials.toByteArray());
- c.getTablesList();
-
- } catch (Exception e) {
- throw new RuntimeException(e);
+
+ client.jwt(jwt);
+ client.getTablesList();
}
}