Hive MetaStore 认证和权限模型

hive.metastore.pre.event.listeners

hive.metastore.pre.event.listeners 是 meta store 实现权限的主要途径。可以设置多个,用 ‘,’ 分开。

<property>
    <name>hive.metastore.pre.event.listeners</name>
    <value/>
    <description>List of comma separated listeners for metastore events.</description>
  </property>

HiveMetaStore$HMSHandler#init

在 handler 的 init 方法里,创建 preListeners

preListeners = MetaStoreUtils.getMetaStoreListeners(MetaStorePreEventListener.class,
          conf, MetastoreConf.getVar(conf, ConfVars.PRE_EVENT_LISTENERS));
preListeners.add(0, new TransactionalValidationListener(conf));

get_database

当 HMSHandler 处理请求时,调用 firePreEvent,传递相应的 event,以 get_database 的代码如下:

@Override
    public Database get_database(final String name) throws NoSuchObjectException, MetaException {
      startFunction("get_database", ": " + name);
      Database db = null;
      Exception ex = null;
      try {
        String[] parsedDbName = parseDbName(name, conf);
        db = get_database_core(parsedDbName[CAT_NAME], parsedDbName[DB_NAME]);
        firePreEvent(new PreReadDatabaseEvent(db, this));
      } catch (MetaException|NoSuchObjectException e) {
        ex = e;
        throw e;
      } finally {
        endFunction("get_database", db != null, ex);
      }
      return db;
    }

PreReadDatabaseEvent

Event type 是 PreEventType.READ_DATABASE。

public class PreReadDatabaseEvent extends PreEventContext {
  private final Database db;

  public PreReadDatabaseEvent(Database db, IHMSHandler handler) {
    super(PreEventType.READ_DATABASE, handler);
    this.db = db;
  }
}

firePreEvent

firePreEvent 调用

private void firePreEvent(PreEventContext event) throws MetaException {
      for (MetaStorePreEventListener listener : preListeners) {
        try {
          listener.onEvent(event);
        } catch (NoSuchObjectException e) {
        // ...
      }
    }

认证是获取用户信息的方式

默认是 通过 UGI 获取 用户信息。 HadoopDefaultMetastoreAuthenticator

<property>
    <name>hive.security.metastore.authenticator.manager</name>
    <value>org.apache.hadoop.hive.ql.security.HadoopDefaultMetastoreAuthenticator</value>
    <description>
      authenticator manager class name to be used in the metastore for authentication. 
      The user defined authenticator should implement interface org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider.
    </description>
  </property>

AuthorizationPreEventListener

当 listeners 配置 时,在 meta store 端实现权限控制。

<property>
      <name>hive.metastore.pre.event.listeners</name>
      <value>org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener</value>
</property>

AuthorizationPreEventListener 用配置 hive.security.metastore.authenticator.manager 获取用户信息。用 hive.security.metastore.authorization.manager 实现鉴权。

<property>
  <name>hive.security.metastore.authenticator.manager</name>
  <value>org.apache.hadoop.hive.ql.security.HadoopDefaultMetastoreAuthenticator</value>
  <description>
    authenticator manager class name to be used in the metastore for authentication. 
    The user defined authenticator should implement interface org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider.
  </description>
</property>
<property>
  <name>hive.security.metastore.authorization.manager</name>
  <value>org.apache.hadoop.hive.ql.security.authorization.DefaultHiveMetastoreAuthorizationProvider</value>
  <description>
    Names of authorization manager classes (comma separated) to be used in the metastore
    for authorization. The user defined authorization class should implement interface
    org.apache.hadoop.hive.ql.security.authorization.HiveMetastoreAuthorizationProvider.
    All authorization manager classes have to successfully authorize the metastore API
    call for the command execution to be allowed.
  </description>
</property>

AuthorizationPreEventListener 使用线程本地变量存储数据

private static final ThreadLocal<Configuration> tConfig = new ThreadLocal<Configuration>() {
    @Override
    protected Configuration initialValue() {
      return new HiveConf(AuthorizationPreEventListener.class);
    }
  };

  private static final ThreadLocal<HiveMetastoreAuthenticationProvider> tAuthenticator
      = new ThreadLocal<HiveMetastoreAuthenticationProvider>() {
    @Override
    protected HiveMetastoreAuthenticationProvider initialValue() {
      try {
        return  (HiveMetastoreAuthenticationProvider) HiveUtils.getAuthenticator(
            tConfig.get(), HiveConf.ConfVars.HIVE_METASTORE_AUTHENTICATOR_MANAGER);
      } catch (HiveException he) {
        throw new IllegalStateException("Authentication provider instantiation failure",he);
      }
    }
  };

  private static final ThreadLocal<List<HiveMetastoreAuthorizationProvider>> tAuthorizers
      = new ThreadLocal<List<HiveMetastoreAuthorizationProvider>>() {
    @Override
    protected List<HiveMetastoreAuthorizationProvider> initialValue() {
      try {
        return  HiveUtils.getMetaStoreAuthorizeProviderManagers(
            tConfig.get(), HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_MANAGER, tAuthenticator.get());
      } catch (HiveException he) {
        throw new IllegalStateException("Authorization provider instantiation failure",he);
      }
    }
  };

  private static final ThreadLocal<Boolean> tConfigSetOnAuths = new ThreadLocal<Boolean>() {
    @Override
    protected Boolean initialValue() {
      return false;
    }
  };

AuthorizationPreEventListener#onEvent 实现

public void onEvent(PreEventContext context) throws MetaException, NoSuchObjectException,
      InvalidOperationException {
      switch (context.getEventType()) {
    case CREATE_TABLE:
      authorizeCreateTable((PreCreateTableEvent)context);
      break;
      // ...
}      

authorizeCreateTable

authorizeCreateTable 调用每个 authorizer 的 authorize 方法进行鉴权。

private void authorizeCreateTable(PreCreateTableEvent context)
      throws InvalidOperationException, MetaException {
    try {
      org.apache.hadoop.hive.ql.metadata.Table wrappedTable = new TableWrapper(context.getTable());
      for (HiveMetastoreAuthorizationProvider authorizer : tAuthorizers.get()) {
        authorizer.authorize(wrappedTable,
            HiveOperation.CREATETABLE.getInputRequiredPrivileges(),
            HiveOperation.CREATETABLE.getOutputRequiredPrivileges());
      }
    } catch (AuthorizationException e) {
      throw invalidOperationException(e);
    } catch (HiveException e) {
      throw metaException(e);
    }
  }

HiveMetastoreAuthorizationProvider 的可选配置项

  • org.apache.hadoop.hive.ql.security.authorization.MetaStoreAuthzAPIAuthorizerEmbedOnly
  • org.apache.hadoop.hive.ql.security.authorization.DefaultHiveMetastoreAuthorizationProvider
  • org.apache.hadoop.hive.ql.security.authorization.StorageBasedAuthorizationProvider

MetaStoreAuthzAPIAuthorizerEmbedOnly

对任何操作都不做鉴权,用于把 meta store 和 hive server 或者 hive cli 启动在同一 JVM 内。

DefaultHiveMetastoreAuthorizationProvider

DefaultHiveMetastoreAuthorizationProvider 继承 BitSetCheckedAuthorizationProvider

public class DefaultHiveMetastoreAuthorizationProvider extends BitSetCheckedAuthorizationProvider
  implements HiveMetastoreAuthorizationProvider {
}
public abstract class BitSetCheckedAuthorizationProvider extends
    HiveAuthorizationProviderBase {
}

BitSetChecker

静态内部类 BitSetChecker,并且有创建 BitSetChecker 的静态方法。 getBitSetChecker

static class BitSetChecker {

    boolean[] inputCheck = null;
    boolean[] outputCheck = null;

    public static BitSetChecker getBitSetChecker(Privilege[] inputRequiredPriv,
        Privilege[] outputRequiredPriv) {
      BitSetChecker checker = new BitSetChecker();
      if (inputRequiredPriv != null) {
        checker.inputCheck = new boolean[inputRequiredPriv.length];
        for (int i = 0; i < checker.inputCheck.length; i++) {
          checker.inputCheck[i] = false;
        }
      }
      if (outputRequiredPriv != null) {
        checker.outputCheck = new boolean[outputRequiredPriv.length];
        for (int i = 0; i < checker.outputCheck.length; i++) {
          checker.outputCheck[i] = false;
        }
      }
      return checker;
    }
  }

authorize 进行全局权限判断

@Override
  public void authorize(Privilege[] inputRequiredPriv,
      Privilege[] outputRequiredPriv) throws HiveException, AuthorizationException {

    BitSetChecker checker = BitSetChecker.getBitSetChecker(inputRequiredPriv,
        outputRequiredPriv);
    boolean[] inputCheck = checker.inputCheck;
    boolean[] outputCheck = checker.outputCheck;

    authorizeUserPriv(inputRequiredPriv, inputCheck, outputRequiredPriv,
        outputCheck);
    checkAndThrowAuthorizationException(inputRequiredPriv, outputRequiredPriv,
        inputCheck, outputCheck, null, null, null, null);
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值