1.hive权限控制需要配置那个配置文件?
2.Hive授权的核心是什么?
3.如何实现 角色的授权和撤销?


Hive从0.10版本(包含0.10版本)以后可以通过元数据来控制权限,Hive-0.10之前的版本对权限的控制主要是通过Linux的用户和用户组来控制,不能对Hive表的CREATE、SELECT、DROP等操作进行控制,当然Hive基于元数据来控制权限也不是完全安全的,目的就是为了防止用户不小心做了不该做的操作。
在使用Hive的元数据配置权限之前必须现在hive-site.xml中配置两个参数,配置参数如下:
  1. <property> 
  2. <name>hive.security.authorization.enabled</name> 
  3. <value>true</value> 
  4. <description>enable or disable the hive clientauthorization</description>
  5. </property>
  6. <property> 
  7. <name>hive.security.authorization.createtable.owner.grants</name> 
  8. <value>ALL</value> 
  9. <description>the privileges automatically granted to the ownerwhenever a table gets created. An example like "select,drop" willgrant select and drop privilege to the owner of the table</description>
  10. </property>
复制代码


hive.security.authorization.enabled 参数是开启权限验证,默认为false。hive.security.authorization.createtable.owner.grants参数是指表的创建者对表拥有所有权限,例如创建一个表table1,这个用户对表table1拥有SELECT、DROP等操作。还有个值是NULL,表示表的创建者无法访问该表,这个肯定是不合理的。

Hive授权的核心就是用户(User)、组(Group)、角色(Role),Hive中的角色和平常认知的角色是有区别的。Hive中的角色可以理解为一部分有一些相同“属性”的用户或组或角色的集合。这里有个递归的概念,就是一个角色可以是一些角色的集合。
举个例子:
  1. 用户     组
  2. 张三   group_db1
  3. 李四   group_db2
  4. 王五  group_bothdb
复制代码



有三个用户分别属于group_db1、group_db2、group _bothdb。group _db1、group _db2、group _bothdb分别表示该组用户可以访问数据库1、数据库2和可以访问1、2两个数据库。现在可以创建role_db1和role_db2,分别并授予访问数据库1和数据库2的权限。这样只要将role_db1赋给group_db1(或者该组的所有用户),将role_db2赋给group_db2,就可以是实现指定用户访问指定数据库。最后创建role_bothdb指向 role_db1、role_db2(role_bothdb不需要指定访问那个数据库),然后role_bothdb授予group_bothdb,则group_bothdb中的用户可以访问两个数据库。
用户和组使用的是Linux机器上的用户和组,而角色必须自己创建。
注意:如果有一个属于组group1的用户jayliu,他通过cli连接到远程的Server上执行操作,而远程的Server上有一个用户jayliu属于group2组,则在权限控制中jayliu是对应的group2组的。

1      创建和删除角色
Hive中的角色定义与关系型数据库中角色的定义类似,它是一种机制,给予那些没有适当权限的所有用户分配一定的权限。下面介绍一下Hive中角色的应用。
1)角色的创建。语法:
  1. CREATE ROLE ROLE_NAME
复制代码



创建一个role_test1角色,命令如下:
  1. hive> create rolerole_test1;
  2. OK
  3. Time taken: 0.106 seconds
复制代码


2)删除角色。语法:
  1. DROP ROLE ROLE_NAME
复制代码



删除role_test1角色,命令如下:
  1. hive> DROP ROLErole_test1;
  2. OK
  3. Time taken: 6.483 seconds
复制代码


2      角色的授权和撤销
角色的授权(GRANT)就是给角色授予创建表、查询表等操作,撤销(REVOKE)反之。语法如下:
  1. GRANT ROLE role_name [,role_name] ... TO principal_specification [, principal_specification] ...
  2. REVOKE ROLE role_name [,role_name] ... FROM principal_specification [, principal_specification]...
  3. principal_specification  :
  4. USER user   |GROUP group   | ROLE role
复制代码


看下面的实例。
1)把role_test1角色授权给jayliu用户,命令如下:
  1. hive> grant rolerole_test1 to user jayliu;
  2. OK
  3. Time taken: 0.102 seconds
复制代码


2)查看jayliu用户被授权的角色,命令如下:
  1. hive> SHOW ROLE GRANTuser jayliu;
  2. OK
  3. role name:role_test1
  4. role name:role_test1
  5. Time taken: 7.913 seconds,Fetched: 2 row(s)
复制代码


3)取消jayliu用户的role_test1角色,操作命令如下:
  1. hive> revoke rolerole_test1 from user jayliu;
  2. OK
  3. Time taken: 0.189 seconds
复制代码


Hive支持的权限控制如下表10-8所示。
表10-8 Hive权限控制
  
       操作
  
     解释
ALL
所有权限
ALTER
允许修改元数据(modify metadata data of  object)---表信息数据
UPDATE
允许修改物理数据(modify physical data of  object)---实际数据
CREATE
允许进行Create操作
DROP
允许进行DROP操作
INDEX
允许建索引(目前还没有实现)
LOCK
当出现并发的使用允许用户进行LOCK和UNLOCK操作
SELECT
允许用户进行SELECT操作
SHOW_DATABASE
允许用户查看可用的数据库



看下面的实例。
1)把select权限授权给jayliu用户,命令如下:
  1. hive> grant select ondatabase default to user jayliu;   
  2. OK
  3. Time taken: 0.188 seconds
复制代码

2)查看jayliu被授予那些操作权限,命令如下:
  1. hive> show grant userjayliu on database default;
  2. OK
  3. database       default        
  4. principalName        jayliu  
  5. principalType USER         
  6. privilege         Select         
  7. grantTime      Thu Jul 11 18:17:39 CST 2013        
  8. grantor root   
  9. Time taken: 7.615 seconds,Fetched: 7 row(s)
复制代码

3)收回jayliu的select权限,操作如下:
  1. hive> revoke select ondatabase default from user jayliu;
  2. OK
  3. Time taken: 0.147 seconds
复制代码

4)查看jayliu用户拥有那些权限:
  1. hive> show grant userjayliu on database default;        
  2. OK
  3. Time taken: 0.032 seconds
复制代码

3      超级管理员权限
Hive本身有权限管理功能,需要通过配置开启。配置文件内容如下:
  1. <property>
  2.    <name>hive.metastore.authorization.storage.checks</name>
  3.     <value>true</value>
  4. </property>
  5. <property>
  6.     <name>hive.metastore.execute.setugi</name>
  7.     <value>false</value>
  8. </property>
  9. <property>
  10.     <name>hive.security.authorization.enabled</name>
  11.     <value>true</value>
  12. </property>
  13. <property>
  14.    <name>hive.security.authorization.createtable.owner.grants</name>
  15.     <value>ALL</value>
  16. </property>
复制代码

其中hive.security.authorization.createtable.owner.grants设置成ALL表示用户对自己创建的表是有所有权限。
开启权限控制有Hive的权限功能还有一个需要完善的地方,那就是“超级管理员”。
Hive中没有超级管理员,任何用户都可以进行Grant/Revoke操作,为了完善“超级管理员”,必须添加hive.semantic.analyzer.hook配置,并实现自己的权限控制类。实现“超级管理员”的步骤如下。
1)编写编写权限控制类,代码如代码清单10-4所示。
            代码清单10-4  hive\udaf\ AvgUDAF.java
  1. package com.autoNavi.hive;
  2. importorg.apache.hadoop.hive.ql.parse.ASTNode;
  3. importorg.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook;
  4. importorg.apache.hadoop.hive.ql.parse.HiveParser;
  5. import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
  6. import org.apache.hadoop.hive.ql.parse.SemanticException;
  7. import org.apache.hadoop.hive.ql.session.SessionState;
  8. public class  HiveAdmin extends AbstractSemanticAnalyzerHook {
  9. private static String admin = "admin";
  10.    @Override
  11. public ASTNodepreAnalyze(HiveSemanticAnalyzerHookContextcontext,
  12. ASTNodeast) throws SemanticException {
  13. switch (ast.getToken().getType()) {
  14. caseHiveParser.TOK_CREATEDATABASE:
  15. caseHiveParser.TOK_DROPDATABASE:
  16. caseHiveParser.TOK_CREATEROLE:
  17. caseHiveParser.TOK_DROPROLE:
  18. caseHiveParser.TOK_GRANT:
  19. caseHiveParser.TOK_REVOKE:
  20. caseHiveParser.TOK_GRANT_ROLE:
  21. caseHiveParser.TOK_REVOKE_ROLE:
  22.              StringuserName = null;
  23. if (SessionState.get() != null
  24. &&SessionState.get().getAuthenticator() != null){
  25. userName=SessionState.get().getAuthenticator().getUserName();
  26.             }
  27. if (!admin.equalsIgnoreCase(userName)) {
  28. thrownewSemanticException(userName
  29.                         + " can't use ADMIN options, except " + admin +".");
  30.             }
  31. break;
  32. default:
  33. break;
  34.         }
  35. returnast;
  36.     }
  37. }
复制代码

2)添加控制类HiveAdmin到Hive的配置文件(hive-site.xml)中,代码如下所示:
  1. <property> 
  2.     <name>hive.semantic.analyzer.hook</name> 
  3.     <value>com.autonavi.hive.HiveAdmin</value> 
  4. </property>
复制代码

  添加了配置文件以后,如果启动了Hive Server,必须关闭重启功能才能生效。
至此,只有admin用户可以进行Grant/Revoke操作。例如,jayliu用户启动Hive的Shell命令,把default数据库中的所有表的查询(SELECT)授权给用户hadoop,命令如下:
  1. hive> GRANT SELECT ON DATABASEdefault TO USER hadoop;
  2. FAILED:SemanticExceptionjayliu can't use ADMIN options, except admin.
复制代码

Hive的权限控制在Hive的生产环境中使用的非常多,在0.10版本之前Hive是没有提供这个功能的。读者使用这个功能的时候一定要确保Hive的版本在0.10以后。
实例:使用 JDBC开发 Hive 程序
在使用 JDBC开发 Hive 程序时,  必须首先开启Hive 的远程服务接口。使用下面命令进行开启:
hive --servicehiveserver &
1      准备测试数据
准备一个文件hiveJDBC.txt,文件内容(每行数据之间用tab键隔开)为:
1    hadoop
2    hive
3    Hbase
   数据准备好了,接下来使用Hive的JDBC来实现对Hive表的数据加载、表结构信息和数据查询等操作。
2      代码实现
Hive的JDBC操作实现表的数据加载、表结构信息和数据查询。代码如代码清单10-3所示。
代码清单10-3  hive\udaf\ HiveJdbcClient.java
  1. packagecom.hive.jdbc;
  2. importjava.sql.Connection;
  3. importjava.sql.DriverManager;
  4. importjava.sql.ResultSet;
  5. importjava.sql.SQLException;
  6. importjava.sql.Statement;
  7. importorg.apache.log4j.Logger;
  8. publicclass HiveJdbcClient {
  9.         private static String driverName ="org.apache.hadoop.hive.jdbc.HiveDriver";
  10.         private static String url ="jdbc:hive://192.168.153.100:10000/default";
  11.         private static String user ="hive";
  12.         private static String password = "hive";
  13.         private static String sql ="";
  14.         private static ResultSet res;
  15.         private static final Logger log =Logger.getLogger(HiveJdbcClient.class);
  16.         public static void main(String[] args){
  17.                 try {
  18.                        Class.forName(driverName);
  19.                         Connection conn =DriverManager.getConnection(url, user, password);
  20.                         Statement stmt =conn.createStatement();
  21.                         // 创建的表名
  22.                         String tableName ="testHiveJDBC";
  23.                         /** 第一步:存在就先删除**/
  24.                         sql = "drop table" + tableName;
  25.                         stmt.executeQuery(sql);
  26.                         /** 第二步:不存在就创建**/
  27.                         sql = "createtable " + tableName + " (key int, value string)
  28. row formatdelimited fields terminated by '\t'";
  29.                         stmt.executeQuery(sql);
  30.                         // 执行“show tables”操作
  31.                         sql = "show tables'" + tableName + "'";
  32.                        System.out.println("Running:" + sql);
  33.                         res = stmt.executeQuery(sql);
  34.                        System.out.println("执行“show tables”运行结果:");
  35.                         if (res.next()) {
  36.                                System.out.println(res.getString(1));
  37.                         }
  38.                         // 执行“describe table”操作
  39.                         sql = "describe" + tableName;
  40.                        System.out.println("Running:" + sql);
  41.                         res =stmt.executeQuery(sql);
  42.                         System.out.println("执行“describe table”运行结果:");
  43.                         while (res.next()){  
  44.                                System.out.println(res.getString(1) + "\t" +res.getString(2));
  45.                         }
  46.                         // 执行“load data intotable”操作
  47.                         String filepath ="/home/hadoop/ziliao/userinfo.txt";
  48.                         sql = "load datalocal inpath '" + filepath + "' into table " + tableName;
  49.                        System.out.println("Running:" + sql);
  50.                         res =stmt.executeQuery(sql);
  51.                            // 执行“select * query”操作
  52.                         sql = "select *from " + tableName;
  53.                        System.out.println("Running:" + sql);
  54.                         res =stmt.executeQuery(sql);
  55.                        System.out.println("执行“select * query”运行结果:");
  56.                         while (res.next()) {
  57.                                System.out.println(res.getInt(1) + "\t" + res.getString(2));
  58.                         }
  59.                         // 执行“regular hive query”操作
  60.                         sql = "selectcount(1) from " + tableName;
  61.                        System.out.println("Running:" + sql);
  62.                         res =stmt.executeQuery(sql);
  63.                        System.out.println("执行“regular hive query”运行结果:");
  64.                         while (res.next()) {
  65.                                System.out.println(res.getString(1));
  66.                         }
  67.                         conn.close();
  68.                         conn = null;
  69.                 } catch (ClassNotFoundExceptione) {
  70.                         e.printStackTrace();
  71.                         log.error(driverName +" not found!", e);
  72.                         System.exit(1);
  73.                 } catch (SQLException e) {
  74.                         e.printStackTrace();
  75.                        log.error("Connection error!", e);
  76.                         System.exit(1);
  77.                 }
  78.         }
  79. }
复制代码

代码实现完成,接下来运行这个代码,操作为Run AS->Java Aplication,Eclipse的控制台会出现如下结果:
  1. Running:show tables 'testHiveJDBC'
  2. 执行“show tables”运行结果:
  3. 'testHiveJDBC'
  4. Running:describe 'testHiveJDBC'
  5. 执行“describe table”运行结果:
  6. key    int
  7. value    string
  8. Running:load data localinpath '/user/hadoop/hive/hiveJDBC.txt' intotable testHiveJDBC
  9. Running:select * from'testHiveJDBC'
  10. 执行“select * query”运行结果:
  11.     hadoop
  12.     hive
  13.     hbase
  14. Running:select count(1)from testHiveJDBC
复制代码

执行“regular hive query”运行结果:
Hive的JDBC接口在实际开发中是经常用到的。和MySQL的JDBC接口非常的类似。给开发人员提供了远程操作Hive的接口。
Logo

更多推荐