caican00 commented on code in PR #3970:
URL: https://github.com/apache/gravitino/pull/3970#discussion_r1663972102
##########
catalogs/catalog-lakehouse-paimon/src/main/java/com/datastrato/gravitino/catalog/lakehouse/paimon/authentication/kerberos/FilesystemBackendProxy.java:
##########
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2024 Datastrato Pvt Ltd.
+ * This software is licensed under the Apache License version 2.
+ */
+
+package
com.datastrato.gravitino.catalog.lakehouse.paimon.authentication.kerberos;
+
+import com.datastrato.gravitino.utils.PrincipalUtils;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.PrivilegedExceptionAction;
+import java.util.Map;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.paimon.catalog.CatalogContext;
+import org.apache.paimon.catalog.FileSystemCatalog;
+import org.apache.paimon.fs.FileIO;
+import org.apache.paimon.fs.Path;
+import org.apache.paimon.fs.hadoop.HadoopFileIO;
+import org.apache.paimon.options.CatalogOptions;
+import org.apache.paimon.options.Options;
+import org.apache.paimon.utils.Pair;
+import org.apache.paimon.utils.Preconditions;
+
+/**
+ * Proxy class for FilesystemCatalog to support kerberos authentication. We
can also make
+ * FilesystemCatalog as a generic type and pass it as a parameter to the
constructor.
+ */
+public class FilesystemBackendProxy implements MethodInterceptor {
+
+ private FileSystemCatalog target;
+ private final CatalogContext catalogContext;
+ private final String kerberosRealm;
+ private final UserGroupInformation proxyUser;
+
+ public FilesystemBackendProxy(
+ FileSystemCatalog target, CatalogContext catalogContext, String
kerberosRealm) {
+ this.target = target;
+ this.catalogContext = catalogContext;
+ this.kerberosRealm = kerberosRealm;
+ try {
+ proxyUser = UserGroupInformation.getCurrentUser();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to get current user", e);
+ }
+ }
+
+ @Override
+ public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy)
+ throws Throwable {
+
+ String proxyKerberosPrincipalName =
PrincipalUtils.getCurrentPrincipal().getName();
+ if (!proxyKerberosPrincipalName.contains("@")) {
+ proxyKerberosPrincipalName =
+ String.format("%s@%s", proxyKerberosPrincipalName, kerberosRealm);
+ }
+
+ UserGroupInformation realUser =
+ UserGroupInformation.createProxyUser(proxyKerberosPrincipalName,
proxyUser);
+
+ return realUser.doAs(
+ (PrivilegedExceptionAction<Object>)
+ () -> {
+ try {
+ updateFileIO(catalogContext);
+ return methodProxy.invoke(target, objects);
+ } catch (Throwable e) {
+ if (RuntimeException.class.isAssignableFrom(e.getClass())) {
+ throw (RuntimeException) e;
+ }
+ throw new RuntimeException("Failed to invoke method", e);
+ }
+ });
+ }
+
+ public FileSystemCatalog getProxy() {
+ Enhancer e = new Enhancer();
+ e.setClassLoader(target.getClass().getClassLoader());
+ e.setSuperclass(target.getClass());
+ e.setCallback(this);
+ // FileSystemCatalog does not have a no argument constructor.
+ return (FileSystemCatalog)
+ e.create(
+ new Class[] {FileIO.class, Path.class, Options.class},
+ new Object[] {
+ target.fileIO(), new Path(target.warehouse()), new
Options(target.options())
+ });
+ }
+
+ /**
+ * Before invoking the doAs method, a Filesystem client has been created
when initializing the
+ * FilesystemCatalog. Therefore, the Filesystem client should be recreated
within the doAs method
+ * to ensure the ugi corresponds to the impersonated user.
+ */
+ private void updateFileIO(CatalogContext catalogContext)
Review Comment:
> @FANNG1 For Iceberg with the Hive backend, different users will use
different Hive clients to access HMS.
maybe i can create new catalog instances for different users in the
proxyPlugin and cache them, instead of using `target` object to access hdfs.
I'm not sure if it works, I'll test it.
and we can also avoid using reflection. WDYT? cc @yuqi1129 @FANNG1
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]