caican00 commented on code in PR #3970:
URL: https://github.com/apache/gravitino/pull/3970#discussion_r1665089525
##########
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:
> `create new catalog instances for different users` also seems hacky for me
:(
Hi @FANNG1 do you have any good ideas for this issue to share?
> In the Iceberg catalog with the hive backend, we will create a new client
pool for each user and cache it for the specific user. I am not sure whether
the Paimon catalog can also adopt this strategy.
@FANNG1 i pushed the newly code, could you help take a look?
##########
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:
> `create new catalog instances for different users` also seems hacky for me
:(
Hi @FANNG1 do you have any good ideas for this issue to share?
> In the Iceberg catalog with the hive backend, we will create a new client
pool for each user and cache it for the specific user. I am not sure whether
the Paimon catalog can also adopt this strategy.
@yuqi1129 i pushed the newly code, could you help take a look?
--
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]