Spark SQL 权限控制

本文探讨了三种控制Spark权限的方法:通过Hive权限控制Spark、改造Spark源码实现权限控制及利用HDFS文件权限控制Spark权限。文章详细介绍了每种方法的操作步骤及优缺点。
背景

Spark如今已经是我们最常用的计算和查询引擎之一,但是很遗憾的是社区版的Spark本身没有任何权限控制手段(据说Spark的Thrift server服务支持create/drop权限控制,但我并未试过,而且只有这种层次的控制并不够),我们当然可以在应用层通过业务功能来从平台上控制用户的权限,但随着业务进化,从中间件层次对Spark做出和hive一样的权限控制也十分重要。由于目前还没有很成熟方案,下面是我的一些探索,给有同样需求的同学一些思路。

1. 通过控制hive权限来控制Spark权限

我们平时使用spark大多数是通过hive元数据来获取数仓中的库表信息,那么我们是否可以通过控制hive的权限来间接控制spark呢?

先说结论,不可行。下边是尝试过程。

首先我们通过root用户,在数仓的db_test1数据库下创建了一张test1表,并插入了简单的数据。结构很简单:
在这里插入图片描述
下面我们使用root用户通过hive cli查询:
在这里插入图片描述
可以正常查出数据,没有问题,接下来我们切换非同组的另一不相关的admin用户,同样通过hive cli来查询这张表:
在这里插入图片描述
提示我们没有查询权限(hive权限控制启用方法此处不再赘述),可见hive权限控制是成功的,下面我们仍然使用admin用户,进入spark-sql cli查询:
在这里插入图片描述
Spark仍然成功查到了数据,可见hive的权限控制是不会影响Spark查询的,猜测hive应该是在执行SQL的时候,通过HiveParser解析SQL时去进行权限控制的,而Spark只是使用了hive的元数据信息,所以不会受到权限影响。

2.改造Spark源码控制SQL权限

在hive权限不会影响spark权限的情况下,如果我们想要和hive共享同一套权限怎么办呢?我们可以尝试去改造Spark源码并重新编译,思路是通过Aspect拦截Spark的方法,实现权限控制。
下载Spark源码后,我们在sql module下新增一个aspect package,新建了一个名为SparkSqlAspect的Scala类
在这里插入图片描述
下面是我添加的代码:

@Aspect
class SparkSqlAspect {
  val execution = "execution(public org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> " +
    "org.apache.spark.sql.SparkSession.sql(java.lang.String)) && args(sqlRaw)"
  @Around(execution)
  def around(pjp: ProceedingJoinPoint, sqlRaw: String): Dataset[Row] = {
    val sql = sqlRaw.trim
    val spark = pjp
      .getThis
      .asInstanceOf[SparkSession]
    val userName = spark
      .sparkContext
      .sparkUser
    if (accessControl(sql, userName, spark)) {
      pjp
        .proceed(pjp.getArgs)
        .asInstanceOf[Dataset[Row]]
    } else {
      throw new IllegalAccessException("Permission denied")
    }
  }

  /**
   * 权限控制
   * @param sql sql内容
   * @param userName 用户名
   * @param spark SparkSession
   * @return Boolean
   */
  def accessControl(sql: String, userName: String, spark: SparkSession): Boolean = {
    val logicalPlan = spark.sessionState.sqlParser.parsePlan(sql)
    import org.apache.spark.sql.catalyst.analysis.UnresolvedRelation
    val tableSeq = logicalPlan
      .collect { case r: UnresolvedRelation => r.tableName }
//  结合sql,tableSeq,userName进行权限控制
    
    true
  }

}

通过拦截spark.sql()等方法,来进行权限控制,比如此处可以链接到hive元数据结合校验。改造完成后,需要重新编译源码。这种方法是可行的,但是不是很推荐,因为对日后升级版本很不利,而且重新编译源码费时费力。

3.通过控制Hadoop的HDFS文件权限来控制Spark权限

HDFS文件系统本身是有rwx这种权限控制的,我们可以通过控制HDFS文件的权限来影响Spark权限,我们仍然使用1中的db_test1库测试,分别使用root和admin用户在这个库下建立两张表test1和test2。
在这里插入图片描述
可以看到默认的表权限为755,理论上我们通过Spark是可以任意查询数据的,下面我们使用root用户进入spark-sql cli,查询test2这张表:
在这里插入图片描述
成功查询出了数据,接下来我们修改test2的权限为700:
在这里插入图片描述
再次使用root用户在spark-sql cli下查询:
在这里插入图片描述
提示没有权限,可见权限控制成功了。
那么这个权限是否也会影响hive呢?答案是肯定的,我们使用root用户在hive cli下尝试:
在这里插入图片描述
同样的效果。主流的Sentry等框架,也是基于这个思路来进行权限控制的。
控制HDFS权限是一种更为底层的控制方式,假设root用户在HDFS上拥有了test2库的读取权限,但在hive上未赋权,那在hive中仍然是无法查询的:
在这里插入图片描述
但在Spark上是可以查询的,原因前边已经论述过了。

到此为止,看起来我们已经可以控制SparkSQL的权限了,但这种方式真的足够安全吗?

需要注意的是,Hadoop开发之初,是假定Hadoop工作在安全的集群环境下的,所以只有单纯的文件权限这种控制。实际这是比较薄弱的,并不是一种非常安全的控制方式,因为Hadoop在登陆时,获取用户名的方式是这样的:

在使用了kerberos的情况下,从javax.security.auth.kerberos.KerberosPrincipal的实例获取username。
在未使用kerberos的情况下,优先读取HADOOP_USER_NAME这个系统环境变量
如果没有读取到,则读取HADOOP_USER_NAME这个java环境变量。
如果没有读取到,则从com.sun.security.auth.NTUserPrincipal或com.sun.security.auth.UnixPrincipal的实例获取username。
如果以上尝试都失败,那么抛出异常LoginException(“Can’t find user name”)。
最终拿username构造org.apache.hadoop.security.User的实例添加到Subject中。

可见我们完全可以模拟一个用户来骗过服务器,我们写一个简单的Demo:

object StartTest {
  val logger: Logger = LoggerFactory.getLogger(StartTest.getClass)

  def main(args: Array[String]): Unit = {
    System.setProperty("HADOOP_USER_NAME", "root")

    SparkSession
      .builder()
      .appName("test")
      .enableHiveSupport()
      .master("local[*]")
      .getOrCreate()
      .sql("select * from db_test1.test1")
      .rdd
      .collect()
  }

}

还是刚才的权限环境,我们通过 System.setProperty(“HADOOP_USER_NAME”, “root”),把用户名写进JAVA环境变量中,将自己的身份伪造成root用户,这样,无论使用哪个用户执行这段程序,都可以读取到db_test1.test1的内容。

可见如果想做到更强力的权限控制,还是应该考虑结合kerberos做身份鉴别,由kerberos保证登录到集群的用户就是他所声称的用户,由HDFS权限来决定用户的权限。

<think>好的,我需要帮助用户了解如何通过Apache Ranger来管理Spark和Paimon的权限。首先,我需要回忆Apache Ranger的基本功能,它是一个集中式的权限管理框架,支持Hadoop生态中的多种组件,比如HDFS、Hive、HBase等。但用户提到的Spark和Paimon可能需要特定的插件或配置。 接下来,我应该考虑Spark的权限管理。Spark本身没有内置的权限控制,通常依赖于底层资源管理器(如YARN)或存储系统(如HDFS)的权限。但结合Ranger的话,可能需要使用Ranger的插件,比如Ranger for Spark SQL,通过定义策略来控制对数据库、表、列的访问。这里需要确认Ranger是否支持Spark SQL,以及如何集成。 然后是Paimon,这是一个流批一体存储系统,可能和Hive类似,需要管理表的读写权限。如果Paimon与Hive Metastore集成,可能可以利用Ranger的Hive插件来管理权限。否则,可能需要Paimon自身的权限机制或扩展Ranger来支持。用户提供的引用中提到了使用Spark Catalog配置Paimon,元数据存储在HDFS,所以可能Paimon的元数据管理方式与Hive类似,这样Ranger的Hive插件可能适用。 接下来需要整理步骤:首先配置Ranger服务,安装对应的插件,然后为Spark和Paimon定义访问策略,最后测试策略是否生效。可能还需要考虑Kerberos集成,确保认证层面的安全。 需要注意的细节包括:Ranger策略的细粒度控制,比如列级权限,以及如何与Spark SQL和Paimon的访问控制结合。此外,用户提到的Spark配置中使用了paimon catalog,可能需要确保Ranger能够识别这个catalog下的元数据,并应用相应的策略。 最后,生成相关问题时要围绕权限管理、集成方式、最佳实践和常见问题来提问,帮助用户进一步探索。</think>### 通过 Apache Ranger 控制 Spark 和 Paimon 权限的最佳实践 #### 1. **权限管理架构设计** - **Apache Ranger 角色**:作为集中式权限管理框架,Ranger 可通过插件机制与 Spark 和 Paimon 集成,提供基于策略的访问控制(如库、表、列级别权限)[^1]。 - **认证集成**:建议与 Kerberos 结合实现身份认证,确保用户身份可信后再通过 Ranger 授权。 #### 2. **Spark 权限配置** - **Spark SQL 集成 Ranger**: - 安装 Ranger Spark Plugin,并在 Spark 配置中启用: ```bash --conf spark.sql.extensions=org.apache.ranger.authorization.spark.authorizer.RangerSparkSQLExtension --conf spark.sql.catalog.paimon=org.apache.paimon.spark.SparkCatalog --conf spark.sql.catalog.paimon.warehouse=hdfs:///path/to/warehouse ``` - 在 Ranger Admin 控制台定义策略(如限制用户对 `paimon` Catalog 下特定表的 SELECT/INSERT 权限)。 - **HDFS 存储层控制**:通过 Ranger HDFS Plugin 控制 `hdfs:///path/to/warehouse` 目录的读写权限,避免绕过 Spark 直接操作文件。 #### 3. **Paimon 权限配置** - **元数据与 Hive Metastore 集成**: - 若 Paimon 使用 Hive Metastore 管理元数据,可直接通过 Ranger Hive Plugin 控制表权限。 - 策略示例:限制用户对 `paimon.db.table1` 的 `SELECT` 操作。 - **独立权限扩展**:若 Paimon 使用独立元数据存储,需开发自定义 Ranger Plugin 或利用其 ACL 功能。 #### 4. **操作步骤** 1. **安装 Ranger 插件**: - 部署 Ranger Spark Plugin 和 HDFS Plugin。 - 同步用户/用户组信息到 Ranger。 2. **定义策略**: - 在 Ranger 控制台创建资源策略(如 `paimon` Catalog 下的表、HDFS 路径)。 - 设置细粒度权限(如列掩码、行过滤)。 3. **验证权限**: ```sql -- 用户执行 Spark SQL 查询时触发权限检查 SELECT * FROM paimon.db.table1 WHERE column1 > 100; ``` 若未授权,Ranger 会拦截并返回权限错误。 #### 5. **注意事项** - **审计与监控**:通过 Ranger Audit 日志追踪所有访问事件。 - **策略同步**:确保 Ranger 策略及时同步到 Spark 和 Paimon 服务端。 - **多租户隔离**:结合 HDFS 目录结构和 Ranger 策略实现租户间数据隔离。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值