This is an automated email from the ASF dual-hosted git repository. linaataustin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sentry.git
The following commit(s) were added to refs/heads/master by this push: new 312add8 SENTRY-2501: Add cache for HMS server filtering hook (Na Li, reviewed by Kalyan Kumar Kalvagadda) 312add8 is described below commit 312add87b8aeeba0cf5876cf77604b7451e98158 Author: lina.li <lina...@cloudera.com> AuthorDate: Tue Feb 19 15:45:26 2019 -0600 SENTRY-2501: Add cache for HMS server filtering hook (Na Li, reviewed by Kalyan Kumar Kalvagadda) --- .../metastore/MetastoreAuthzBindingBase.java | 43 ++++++++++++++++++++++ .../metastore/SentryMetaStoreFilterHook.java | 21 +++++++---- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBindingBase.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBindingBase.java index cdb6de4..2940a1e 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBindingBase.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBindingBase.java @@ -41,11 +41,13 @@ import org.apache.hadoop.hive.metastore.events.PreDropTableEvent; import org.apache.hadoop.hive.metastore.events.PreEventContext; import org.apache.hadoop.hive.metastore.events.PreReadDatabaseEvent; import org.apache.hadoop.hive.metastore.events.PreReadTableEvent; +import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hadoop.hive.ql.plan.HiveOperation; import org.apache.hadoop.hive.shims.Utils; import org.apache.sentry.binding.hive.authz.HiveAuthzBinding; import org.apache.sentry.binding.hive.conf.HiveAuthzConf; import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars; +import org.apache.sentry.core.common.exception.SentryGroupNotFoundException; import org.apache.sentry.core.common.utils.PathUtils; import org.apache.sentry.core.model.db.AccessURI; import org.apache.sentry.core.model.db.DBModelAuthorizable; @@ -62,6 +64,11 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Set; +import org.apache.sentry.provider.cache.PrivilegeCache; +import org.apache.sentry.provider.cache.SimplePrivilegeCache; +import org.apache.sentry.provider.common.AuthorizationProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Sentry binding for Hive Metastore. The binding is integrated into Metastore @@ -132,6 +139,8 @@ public abstract class MetastoreAuthzBindingBase extends MetaStorePreEventListene } } + private static final Logger LOG = LoggerFactory + .getLogger(MetastoreAuthzBindingBase.class); private HiveAuthzConf authzConf; private final Server authServer; private final HiveConf hiveConf; @@ -467,6 +476,40 @@ public abstract class MetastoreAuthzBindingBase extends MetaStorePreEventListene return hiveAuthzBinding; } + // create HiveAuthzBinding with PrivilegeCache + public static HiveAuthzBinding getHiveBindingWithPrivilegeCache(HiveAuthzBinding hiveAuthzBinding, + String userName) throws SemanticException { + // get the original HiveAuthzBinding, and get the user's privileges by AuthorizationProvider + AuthorizationProvider authProvider = hiveAuthzBinding.getCurrentAuthProvider(); + + if (authProvider == null) { + LOG.warn("authProvider is null. Can not create HiveAuthzBinding with privilege cache for Metastore."); + return hiveAuthzBinding; + } + + try { + Set<String> groups; + try { + groups = authProvider.getGroupMapping().getGroups(userName); + } catch (SentryGroupNotFoundException e) { + groups = Collections.emptySet(); + LOG.debug("Could not find groups for user: " + userName); + } + Set<String> userPrivileges = + authProvider.getPolicyEngine().getPrivileges(groups, Sets.newHashSet(userName), + hiveAuthzBinding.getActiveRoleSet(), hiveAuthzBinding.getAuthServer()); + + // create PrivilegeCache using user's privileges + PrivilegeCache privilegeCache = new SimplePrivilegeCache(userPrivileges); + // create new instance of HiveAuthzBinding whose backend provider should be SimpleCacheProviderBackend + return new HiveAuthzBinding(HiveAuthzBinding.HiveHook.HiveMetaStore, hiveAuthzBinding.getHiveConf(), + hiveAuthzBinding.getAuthzConf(), privilegeCache); + } catch (Exception e) { + LOG.error("Can not create HiveAuthzBinding with privilege cache for Metastore."); + throw new SemanticException(e); + } + } + protected String getUserName() throws MetaException { try { return Utils.getUGI().getShortUserName(); diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetaStoreFilterHook.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetaStoreFilterHook.java index 312c5db..8e09490 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetaStoreFilterHook.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetaStoreFilterHook.java @@ -207,11 +207,12 @@ public class SentryMetaStoreFilterHook implements MetaStoreFilterHook { private List<String> filterDb(List<String> dbList) { // If the user is part of the Sentry service user list, then skip the authorization and // do not filter the objects. - if (!needsAuthorization(authzBindingFactory.getUserName())) { + String userName = authzBindingFactory.getUserName(); + if (!needsAuthorization(userName)) { return dbList; } - try (HiveAuthzBinding authzBinding = getHiveAuthzBinding()) { + try (HiveAuthzBinding authzBinding = getHiveAuthzBinding(userName)) { MetastoreAuthzObjectFilter<String> filter = new MetastoreAuthzObjectFilter<>(authzBinding, new ObjectExtractor<String>() { @Override @@ -242,11 +243,12 @@ public class SentryMetaStoreFilterHook implements MetaStoreFilterHook { private List<String> filterTab(String dbName, List<String> tabList) { // If the user is part of the Sentry service user list, then skip the authorization and // do not filter the objects. - if (!needsAuthorization(authzBindingFactory.getUserName())) { + String userName = authzBindingFactory.getUserName(); + if (!needsAuthorization(userName)) { return tabList; } - try (HiveAuthzBinding authzBinding = getHiveAuthzBinding()) { + try (HiveAuthzBinding authzBinding = getHiveAuthzBinding(userName)) { MetastoreAuthzObjectFilter<String> filter = new MetastoreAuthzObjectFilter<>(authzBinding, new ObjectExtractor<String>() { @Override @@ -277,11 +279,12 @@ public class SentryMetaStoreFilterHook implements MetaStoreFilterHook { private List<Table> filterTab(List<Table> tabList) { // If the user is part of the Sentry service user list, then skip the authorization and // do not filter the objects. - if (!needsAuthorization(authzBindingFactory.getUserName())) { + String userName = authzBindingFactory.getUserName(); + if (!needsAuthorization(userName)) { return tabList; } - try (HiveAuthzBinding authzBinding = getHiveAuthzBinding()) { + try (HiveAuthzBinding authzBinding = getHiveAuthzBinding(userName)) { MetastoreAuthzObjectFilter<Table> filter = new MetastoreAuthzObjectFilter<>(authzBinding, new ObjectExtractor<Table>() { @Override @@ -303,14 +306,16 @@ public class SentryMetaStoreFilterHook implements MetaStoreFilterHook { } /** - * load Hive auth provider + * load Hive auth provider with cache * @return * @throws MetaException */ - private HiveAuthzBinding getHiveAuthzBinding() throws MetaException { + private HiveAuthzBinding getHiveAuthzBinding(String userName) throws MetaException { if (hiveAuthzBinding == null) { try { hiveAuthzBinding = authzBindingFactory.fromMetaStoreConf(hiveConf, authzConf); + hiveAuthzBinding = MetastoreAuthzBindingBase + .getHiveBindingWithPrivilegeCache(hiveAuthzBinding, userName); } catch (Exception e) { throw new MetaException("The Sentry/Hive authz binding could not be created: " + e.getMessage());