Hive數(shù)據(jù)倉庫之權(quán)限管理

Hadoop/Hive自帶權(quán)限控制

延續(xù)數(shù)據(jù)倉庫之Hive快速入門 - 離線&實時數(shù)倉架構(gòu)一文,本文將介紹一下Hadoop/Hive自帶的權(quán)限控制,權(quán)限控制是大數(shù)據(jù)平臺非常重要的一部分,關(guān)乎數(shù)據(jù)安全。

集群安全下需求:

  • 支持多組件,最好能支持當前大數(shù)據(jù)技術(shù)棧的主要組件,HDFS、HBASE、HIVE、 YARN、KAFKA等
  • 支持細粒度的權(quán)限控制,可以達到HIVE列,HDFS目錄,HBASE列,YARN隊列
  • 開源,社區(qū)活躍,按照現(xiàn)有的集群情況改動盡可能的小,而且要符合業(yè)界的趨勢。

現(xiàn)有方案:

  • Hadoop、Hive本 身的權(quán)限控制
  • Kerberos安全認證
  • Apache Ranger權(quán)限管理方案

Hadoop權(quán)限:

  • Hadoop分布式文件系統(tǒng)實現(xiàn)了一個和POSIX系統(tǒng)類似的文件和目錄的權(quán)限模型
  • 每個文件和目錄有一個所有者(owner)和一個組(group)
  • 文件或目錄對其所有者、同組的其他用戶以及所有其他用戶分別有著不同的權(quán)限
  • 文件或目錄操作都傳遞路徑名給NameNode,對路徑做權(quán)限檢查
  • 啟動NameNode的用戶是超級用戶,能夠通過所有的權(quán)限檢查
  • 通過配置可以指定一組特定的用戶為超級用戶

Hive權(quán)限:

  • Hive可以基于文件存儲級別的權(quán)限管理
  • Hive可以基于元數(shù)據(jù)的權(quán)限管理
  • User:是基于linux用戶的user
  • Group:是linux層面上的用戶組
  • Role:角色在Hive里面創(chuàng)建,給角色添加權(quán)限,把角色賦予給user
  • Hive中沒有超級管理員,任何用戶都可以進行Grant/Revoke操作
  • 開發(fā)實現(xiàn)自己的權(quán)限控制類,確保某個用戶為超級用戶

實操Hive的權(quán)限操作

首先添加一個系統(tǒng)用戶:

[root@hadoop01 ~]# useradd hive

test這個表的查詢權(quán)限賦予給hive這個用戶:

0: jdbc:hive2://localhost:10000> grant select on table test to user hive;
No rows affected (0.12 seconds)
0: jdbc:hive2://localhost:10000> 

切換到hive用戶:

[root@hadoop01 ~]# sudo su - hive

進入交互命令終端,可以正常執(zhí)行查詢語句:

[hive@hadoop01 ~]$ beeline -u jdbc:hive2://localhost:10000 -n hive
...

0: jdbc:hive2://localhost:10000> select user_name from test;
+------------+
| user_name  |
+------------+
| Tom        |
| Jerry      |
| Jim        |
| Angela     |
| Ann        |
| Bella      |
| Bonnie     |
| Caroline   |
+------------+
8 rows selected (0.075 seconds)
0: jdbc:hive2://localhost:10000> 

但是如果執(zhí)行其他操作則會報錯提示不支持該操作:

0: jdbc:hive2://localhost:10000> delete from test where user_id='f4914b91c5284b01832149776ca53c8d';
Error: Error while compiling statement: FAILED: SemanticException [Error 10294]: Attempt to do update or delete using transaction manager that does not support these operations. (state=42000,code=10294)
0: jdbc:hive2://localhost:10000> 

如此一來,我們就可以限制Hive中用戶對于某些表的操作權(quán)限。但之前也提到了,Hive中沒有超級管理員,任何用戶都可以進行Grant/Revoke操作,這使得權(quán)限管理失去意義。為了解決這個問題,就需要我們開發(fā)實現(xiàn)自己的權(quán)限控制類,確保某個用戶為超級用戶。

首先創(chuàng)建一個空Maven項目,然后添加hive-exec依賴,完整的pom文件內(nèi)容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>hive-security-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

實現(xiàn)自定義權(quán)限控制類:

package com.example.hive.security;

import com.google.common.base.Joiner;
import org.apache.hadoop.hive.ql.parse.*;
import org.apache.hadoop.hive.ql.session.SessionState;

/**
 * 自定義Hive的超級用戶
 *
 * @author 01
 * @date 2020-11-09
 **/
public class HiveAdmin extends AbstractSemanticAnalyzerHook {

    /**
     * 定義超級用戶,可以定義多個
     */
    private static final String[] ADMINS = {"root"};

    /**
     * 權(quán)限類型列表
     */
    private static final int[] TOKEN_TYPES = {
            HiveParser.TOK_CREATEDATABASE, HiveParser.TOK_DROPDATABASE,
            HiveParser.TOK_CREATEROLE, HiveParser.TOK_DROPROLE,
            HiveParser.TOK_GRANT, HiveParser.TOK_REVOKE,
            HiveParser.TOK_GRANT_ROLE, HiveParser.TOK_REVOKE_ROLE,
            HiveParser.TOK_CREATETABLE
    };

    /**
     * 獲取當前登錄的用戶名
     *
     * @return 用戶名
     */
    private String getUserName() {
        boolean hasUserName = SessionState.get() != null &&
                SessionState.get().getAuthenticator().getUserName() != null;

        return hasUserName ? SessionState.get().getAuthenticator().getUserName() : null;
    }

    private boolean isInTokenTypes(int type) {
        for (int tokenType : TOKEN_TYPES) {
            if (tokenType == type) {
                return true;
            }
        }

        return false;
    }

    private boolean isAdmin(String userName) {
        for (String admin : ADMINS) {
            if (admin.equalsIgnoreCase(userName)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public ASTNode preAnalyze(HiveSemanticAnalyzerHookContext context, ASTNode ast) throws SemanticException {
        if (!isInTokenTypes(ast.getToken().getType())) {
            return ast;
        }

        String userName = getUserName();
        if (isAdmin(userName)) {
            return ast;
        }

        throw new SemanticException(userName +
                " is not Admin, except " +
                Joiner.on(",").join(ADMINS)
        );
    }
}

將代碼打包,上傳到服務(wù)器上:

[root@hadoop01 ~]# ls jars/
hive-security-test-1.0-SNAPSHOT.jar
[root@hadoop01 ~]# 

將其拷貝到Hive的lib目錄下:

[root@hadoop01 ~]# cp jars/hive-security-test-1.0-SNAPSHOT.jar /usr/local/apache-hive-3.1.2-bin/lib/

在hive的hive-site.xml文件中,增加如下配置:

[root@hadoop01 ~]# vim /usr/local/apache-hive-3.1.2-bin/conf/hive-site.xml
<configuration>

    ...
    
    <property>
        <name>hive.users.in.admin.role</name>
        <value>root</value>
        <description>定義超級管理員,啟動的時候會自動創(chuàng)建</description>
    </property>
    <property>
        <name>hive.security.authorization.enabled</name>
        <value>true</value>
        <description>開啟權(quán)限</description>
    </property>
    <property>
        <name>hive.security.authorization.createtable.owner.grants</name>
        <value>ALL</value>
        <description>表的創(chuàng)建者對表擁有所有權(quán)限</description>
    </property>
    <property>
        <name>hive.security.authorization.task.factory</name>
        <value>org.apache.hadoop.hive.ql.parse.authorization.HiveAuthorizationTaskFactoryImpl</value>
        <description>進行權(quán)限控制的配置</description>
    </property>
    <property>
        <name>hive.semantic.analyzer.hook</name>
        <value>com.example.hive.security.HiveAdmin</value>
        <description>使用鉤子程序,識別超級管理員,進行授權(quán)控制</description>
    </property>
</configuration>

重啟Hive:

[root@hadoop01 ~]# jps
12401 ResourceManager
12898 RunJar
22338 Jps
12500 NodeManager
11948 NameNode
12204 SecondaryNameNode
12047 DataNode
[root@hadoop01 ~]# kill -15 12898
[root@hadoop01 ~]# nohup hiveserver2 -hiveconf hive.execution.engine=mr &

進入Hive中查看一下角色列表,看看配置是否生效:

[root@hadoop01 ~]# beeline -u jdbc:hive2://localhost:10000 -n root
...

0: jdbc:hive2://localhost:10000> set role admin;  # 將當前用戶角色設(shè)置為admin
No rows affected (0.027 seconds)
0: jdbc:hive2://localhost:10000> show roles;  # 查看角色列表
+---------+
|  role   |
+---------+
| admin   |
| public  |
+---------+
2 rows selected (0.026 seconds)
0: jdbc:hive2://localhost:10000> 

測試授權(quán)操作:

0: jdbc:hive2://localhost:10000> use hive_test;
No rows affected (0.028 seconds)
0: jdbc:hive2://localhost:10000> grant select on table bucket_table to user hive;
No rows affected (0.146 seconds)
0: jdbc:hive2://localhost:10000> 

切換到hive用戶:

[root@hadoop01 ~]# sudo su - hive

進入交互命令終端,此時執(zhí)行grant語句就會報錯,從報錯提示可以看到該錯誤是從我們實現(xiàn)的Hook類里拋出來的:

[hive@hadoop01 ~]$ beeline -u jdbc:hive2://localhost:10000 -n hive
...

0: jdbc:hive2://localhost:10000> grant select on table partition_table to user hive;
Error: Error while compiling statement: FAILED: SemanticException hive is not Admin, except root (state=42000,code=40000)
0: jdbc:hive2://localhost:10000> 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容