首页 > 其他分享 >dremio PrivilegeCatalog 接口简单说明

dremio PrivilegeCatalog 接口简单说明

时间:2023-01-05 20:00:22浏览次数:162  
标签:dremio PrivilegeCatalog 接口 throw user key public datasetConfig

PrivilegeCatalog 实际是一个权限检查的能力,同时dremio 的StoragePlugin 也提供了一个安全check 能力

StoragePlugin安全检查

 boolean hasAccessPermission(String user, NamespaceKey key, DatasetConfig datasetConfig);

可以看出需要一个用户,namespacekey 以及数据集的配置信息(namespace 服务模块的dataset.proto 提供的完整的介绍)

PrivilegeCatalog提供接口约定

/**
 * Interface to perform privilege checking on sources
 */
public interface PrivilegeCatalog {
  /**
   * Validate user's privilege.
   * @param key
   * @param privilege
   */
  void validatePrivilege(NamespaceKey key, Privilege privilege);
 
  /**
   * Validate user's ownership.
   * @param key
   */
  void validateOwnership(NamespaceKey key);
}

Privilege 定义(属于SqlGrant 中的一个枚举),基本包含了dremio 当前可以提供的权限能力了

 public enum Privilege {
    VIEW_JOB_HISTORY,
    ALTER_REFLECTION,
    SELECT,
    ALTER,
    VIEW_REFLECTION,
    MODIFY,
    MANAGE_GRANTS,
    CREATE_TABLE,
    DROP,
    EXTERNAL_QUERY,
    INSERT,
    TRUNCATE,
    DELETE,
    UPDATE,
    CREATE_USER,
    CREATE_ROLE,
    EXECUTE,
    CREATE_SOURCE,
    UPLOAD_FILE,
    ALL
  }
 
  public enum GranteeType {
    USER,
    ROLE
  }
 
  public enum GrantType {
    PROJECT,
    PDS,
    VDS,
    FOLDER,
    SOURCE,
    SPACE,
    FUNCTION
  }
  • 实现子类

 

 

一些实现说明

因为权限属于企业版的特性,默认社区版木有提供的此能力,StoragePlugin 提供的能力从社区版一些实现来说主要面向用户扮演场景,以及底层关联权限的判断
(比如hive)
比如文件存储系统的实现

 
public boolean hasAccessPermission(String user, NamespaceKey key, DatasetConfig datasetConfig) {
    if (config.isImpersonationEnabled()) {
      if (datasetConfig.getReadDefinition() != null) { // allow accessing partial datasets
        FileSystem userFs;
        try {
          userFs = createFS(user);
        } catch (IOException ioe) {
          throw new RuntimeException("Failed to check access permission", ioe);
        }
        final List<TimedRunnable<Boolean>> permissionCheckTasks = Lists.newArrayList();
 
        permissionCheckTasks.addAll(getUpdateKeyPermissionTasks(datasetConfig, userFs));
        permissionCheckTasks.addAll(getSplitPermissionTasks(datasetConfig, userFs, user));
 
        try {
          Stopwatch stopwatch = Stopwatch.createStarted();
          final List<Boolean> accessPermissions = TimedRunnable.run("check access permission for " + key, logger, permissionCheckTasks, 16);
          stopwatch.stop();
          logger.debug("Checking access permission for {} took {} ms", key, stopwatch.elapsed(TimeUnit.MILLISECONDS));
          for (Boolean permission : accessPermissions) {
            if (!permission) {
              return false;
            }
          }
        } catch (FileNotFoundException fnfe) {
          throw UserException.invalidMetadataError(fnfe)
            .addContext(fnfe.getMessage())
            .setAdditionalExceptionContext(new InvalidMetadataErrorContext(ImmutableList.of(key.getPathComponents())))
            .buildSilently();
        } catch (IOException ioe) {
          throw new RuntimeException("Failed to check access permission", ioe);
        }
      }
    }
    return true;
  }

hive 实现

public boolean hasAccessPermission(String user, NamespaceKey key, DatasetConfig datasetConfig) {
    if (!isOpen.get()) {
      throw buildAlreadyClosedException();
    }
 
    if (!metastoreImpersonationEnabled) {
      return true;
    }
 
    try {
      final HiveMetadataUtils.SchemaComponents schemaComponents = HiveMetadataUtils.resolveSchemaComponents(key.getPathComponents(), true);
      final Table table = clientsByUser
        .get(user).getTable(schemaComponents.getDbName(), schemaComponents.getTableName(), true);
      if (table == null) {
        return false;
      }
      if (storageImpersonationEnabled) {
        if (datasetConfig.getReadDefinition() != null && datasetConfig.getReadDefinition().getReadSignature() != null) {
          final HiveReadSignature readSignature = HiveReadSignature.parseFrom(datasetConfig.getReadDefinition().getReadSignature().toByteArray());
          // for now we only support fs based read signatures
          if (readSignature.getType() == HiveReadSignatureType.FILESYSTEM) {
            // get list of partition properties from read definition
            HiveTableXattr tableXattr = HiveTableXattr.parseFrom(datasetConfig.getReadDefinition().getExtendedProperty().asReadOnlyByteBuffer());
            return hasFSPermission(getUsername(user), key, readSignature.getFsPartitionUpdateKeysList(), tableXattr);
          }
        }
      }
      return true;
    } catch (TException e) {
      throw UserException.connectionError(e)
        .message("Unable to connect to Hive metastore: %s", e.getMessage())
        .build(logger);
    } catch (ExecutionException | InvalidProtocolBufferException e) {
      throw new RuntimeException("Unable to connect to Hive metastore.", e);
    } catch (UncheckedExecutionException e) {
      Throwable rootCause = ExceptionUtils.getRootCause(e);
      if(rootCause instanceof TException) {
        throw UserException.connectionError(e)
          .message("Unable to connect to Hive metastore: %s", rootCause.getMessage())
          .build(logger);
      }
 
      Throwable cause = e.getCause();
      if (cause instanceof AuthorizerServiceException || cause instanceof RuntimeException) {
        throw e;
      }
      logger.error("User: {} is trying to access Hive dataset with path: {}.", this.getName(), key, e);
    }
 
    return false;
  }

CatalogImpl 默认实现(实现都为空,如果需要自己实现,返回一个通用的runtime 类型的exception 就行了,具体可以使用UserException)

  @Override
  public void validatePrivilege(NamespaceKey key, SqlGrant.Privilege privilege) {
    // For the default implementation, don't validate privilege.
  }
 
  @Override
  public void validateOwnership(NamespaceKey key) {
    // For the default implementation, don't validate privilege.
  }

当前使用的地方validatePrivilege的地方(从开源系统来说主要是关于sql handler的)

 

 

说明

PrivilegeCatalog 是一个强大的安全接口定义,实现此接口可以做一些方便的安全控制,当时社区版木有提供,我们可以自己尝试扩展
有一点比较特殊的就是实际sql 查询权限处理的并没有(如果思考下,我们也并不需要,因为catalog 元数据部分已经包含了实际可以使用的数据集了
直接直接查询就可以了,因为如果集成了访问控制的,会包含一个用户自己的namespaceservice)

参考资料

https://docs.dremio.com/software/security/rbac/rbac-structure/
sabot/kernel/src/main/java/com/dremio/exec/catalog/PrivilegeCatalog.java
sabot/kernel/src/main/java/com/dremio/exec/store/StoragePlugin.java
services/namespace/src/main/proto/dataset.proto
common/src/main/java/com/dremio/common/exceptions/UserException.java

标签:dremio,PrivilegeCatalog,接口,throw,user,key,public,datasetConfig
From: https://www.cnblogs.com/rongfengliang/p/17028742.html

相关文章

  • 函数式接口
    1.函数式接口只能含有1个方法的接口,入参可以有多个,出参可有可无定义接口@FunctionalInterfacepublicinterfaceReceiverGetter{ List<Receiver>apply(ResGroupr......
  • 更优雅的计算方法或接口耗时
    一、背景开发时,记录某方法或任务的执行时间,或者一段代码的执行时间,如果使用System.currentTimeMillis(),很麻烦且不直观。spring-framework和apache-common包,都提供了Stop......
  • C#调用VC的DLL的接口函数参数类型转换一览表
    handle---------IntPtrhwnd-----------IntPtrchar*----------stringint*-----------refintint&-----------refintvoid*----------IntPtrunsignedchar*-----refbyt......
  • 接口测试常见面试题
    为什么要做接口测试?如下图一个提现功能比如这个输入框,平常拿到这个web页面,会对输入框做用例设计:输入一个负数(如:-100),点提交输入金额为0(如:0),点提交输入金额为0-100的数......
  • python接口自动化系列 - openpyxl库封装04
    前言为了更好的让openpyxl在工作中使用,将openpyxl的常用操作封装起来,这样不仅复用性高,而且阅读性好fromopenpyxlimportload_workbookfromopenpyxl.stylesimportP......
  • dremio ManagedStoragePlugin 简单说明
    ManagedStoragePlugin从字面意思可以看出就是托管存储插件,从目前官方的设计来说就是将自己开发的存储扩展,包装为dremio可以管理的插件(统一模型以及统一处理)ManagedSto......
  • dremio SourceCatalog 服务说明
    SourceCatalog主要进行source的管理,包含了获取信息,创建,更新,删除,包含了不同的实现SourceCatalog服务定义/***Interfacetoperformactionsonsources.......
  • 生产环境下包含refresh_Token接口报错nginx配置
    一、问题现象使用nginx代理项目,生产环境下,包含refresh_Token的接口报错,开发环境下却正常。二、原因nginx默认request的header内容参数下划线时会自动忽略掉,需要添加以下......
  • Python 调用Zoomeye搜索接口
    钟馗之眼是一个强大的搜索引擎,不同于百度谷歌,它主要收集网络中的主机,服务等信息,国内互联网安全厂商知道创宇开放了他们的海量数据库,对之前沉淀的数据进行了整合、整理,打造了......
  • 嵌入式:I/O接口扩展
    嵌入式:I/O接口扩展S3C2410A共有117个多功能复用输入输出口(I/O口),分为8组PORTA~PORTH。PORTA除了作为功能口外,它只作为输出口使用;其余的PORTB~PORTH都可以作为输入输出口使......