hive show current roles问题

本文探讨了Apache Hive 0.13.1中show current roles命令的问题,并详细解析了该命令在Hive V2授权模式下的支持情况。通过深入分析源代码,指出了如何配置Hive以启用V2授权模式并成功执行该命令。

今天hive user maillist上有人问show current roles命令问题:

1
2
3
4
5
6
I am trying to run ‘Show current roles’ on Apache hive  0.13 . 1  but getting following error,
hive> SHOW CURRENT ROLES;
Error in role operation show_current_role on role name  null , error message Unkown role operation show_current_role
FAILED: Execution Error,  return  code  1  from org.apache.hadoop.hive.ql.exec.DDLTask
Can someone tell me whether  this  command is supported on apache Hive  0.13 . 1  or not. If it is supported the what could be the issue.
Any pointer would be really helpful.

在我的印象中,这个命令应该不存在才对。。手动运行了一下,果然报错,仔细看日志,可以看到命令式可以完成parse和analyzer阶段的,运行的时候报错,
按我的理解,如果sql不支持的话应该在parse阶段就会出错

1
2
3
4
5
6
7
8
9
14 / 11 / 20  11 : 22 : 55  INFO ql.Driver: Starting command: show current roles
14 / 11 / 20  11 : 22 : 55  INFO log.PerfLogger: </PERFLOG method=TimeToSubmit start= 1416453775411  end= 1416453775795  duration= 384  from=org.apache.hadoop.hive.ql.Driver>
14 / 11 / 20  11 : 22 : 55  INFO log.PerfLogger: <PERFLOG method=runTasks from=org.apache.hadoop.hive.ql.Driver>
14 / 11 / 20  11 : 22 : 55  INFO log.PerfLogger: <PERFLOG method=task.DDL.Stage- 0  from=org.apache.hadoop.hive.ql.Driver>
Error in role operation show_current_role on role name  null , error message Unkown role operation show_current_role
14 / 11 / 20  11 : 22 : 55  ERROR exec.Task: Error in role operation show_current_role on role name  null , error message Unkown role operation show_current_role
FAILED: Execution Error,  return  code  1  from org.apache.hadoop.hive.ql.exec.DDLTask
14 / 11 / 20  11 : 22 : 55  ERROR ql.Driver: FAILED: Execution Error,  return  code  1  from org.apache.hadoop.hive.ql.exec.DDLTask
14 / 11 / 20  11 : 22 : 55  DEBUG ql.Driver: Shutting down query show current roles

根据堆栈信息,show current roles命令是由DDLTask执行的,看其具体实现:

1
2
3
4
5
   private  int  roleDDL(RoleDDLDesc roleDDLDesc)  throws  HiveException, IOException {
     if (SessionState.get().isAuthorizationModeV2()){
       return  roleDDLV2(roleDDLDesc);   //如果是v2的验证方式,调用roleDDLV2
     }
....

在roleDDLV2中可以看到show current role命令的处理:

1
2
3
4
5
6
7
8
9
10
11
     private  int  roleDDLV2(RoleDDLDesc roleDDLDesc)  throws  HiveException, IOException {
     HiveAuthorizer authorizer = SessionState.get().getAuthorizerV2();
     RoleDDLDesc.RoleOperation operation = roleDDLDesc.getOperation();
     //call the appropriate hive authorizer function
     switch (operation){
...
     case  SHOW_CURRENT_ROLE:
       List<String> roleNames = authorizer.getCurrentRoleNames();
       writeListToFileAfterSort(roleNames, roleDDLDesc.getResFile());
       break ;
...

即show current role这个语法在v2里面支持,那么什么时候SessionState.get().isAuthorizationModeV2()为true呢?来看看SessionState类,isAuthorizationModeV2调用getAuthorizationMode,getAuthorizationMode调用setupAuth

1
2
3
4
5
6
7
8
9
10
11
12
13
public  AuthorizationMode getAuthorizationMode(){
     setupAuth();    //调用setupAuth类设置authorizer和authorizerV2
     if (authorizer !=  null ){
       return  AuthorizationMode.V1;
     } else  if (authorizerV2 !=  null ){
       return  AuthorizationMode.V2;
     }
     //should not happen - this should not get called before this.start() is called
     throw  new  AssertionError( "Authorization plugins not initialized!" );
   }
   public  boolean  isAuthorizationModeV2(){
     return  getAuthorizationMode() == AuthorizationMode.V2;
   }

如果要让AuthorizationMode.V2成立,需要让authorizer为null,authorizerV2不为null才可以,设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
authorizer和authorizerV2是在setupAuth方法中实现的
   private  HiveAuthorizationProvider authorizer;
   private  HiveAuthorizer authorizerV2;
...
   private  void  setupAuth() {
     if  (authenticator !=  null ) {
       // auth has been initialized
       return ;
     }
     try  {
...
       authorizer = HiveUtils.getAuthorizeProviderManager(conf,
           HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER, authenticator,  true );   //hive.security.authorization.manager 默认为org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider         
       if  (authorizer ==  null ) {  //authorizer的值为null时,才可以有机会返回v2
         // if it was null, the new authorization plugin must be specified in
         // config
         HiveAuthorizerFactory authorizerFactory = HiveUtils.getAuthorizerFactory(conf,
             HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER);
         authorizerV2 = authorizerFactory.createHiveAuthorizer( new  HiveMetastoreClientFactoryImpl(),
             conf, authenticator);
         authorizerV2.applyAuthorizationConfigPolicy(conf);
         // create the create table grants with new config
         createTableGrants = CreateTableAutomaticGrant.create(conf);
       }
..

因为hive.security.authorization.manager默认为org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider,所以为authorizer为V1,要想设置为v2,需要让HiveUtils.getAuthorizeProviderManager返回null
HiveUtils.getAuthorizeProviderManager中可以获取设置的authorizer的具体实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   public  static  HiveAuthorizationProvider getAuthorizeProviderManager(
       Configuration conf, HiveConf.ConfVars authorizationProviderConfKey,
       HiveAuthenticationProvider authenticator,  boolean  nullIfOtherClass)  throws  HiveException {
     String clsStr = HiveConf.getVar(conf, authorizationProviderConfKey);  //由hive.security.authorization.manager的设置获取类名
     HiveAuthorizationProvider ret =  null ;
     try  {
       Class<?  extends  HiveAuthorizationProvider> cls =  null ;
       if  (clsStr ==  null  || clsStr.trim().equals( "" )) {  //如果为null或者设置为空,则实现类为DefaultHiveAuthorizationProvider
         cls = DefaultHiveAuthorizationProvider. class ;
       else  {
         Class<?> configClass = Class.forName(clsStr,  true , JavaUtils.getClassLoader());  //否则为具体的实现的类
         if (nullIfOtherClass && !HiveAuthorizationProvider. class .isAssignableFrom(configClass) ){  //配置的类和HiveAuthorizationProvider类没有关系时,返回null
           return  null ;
         }
         cls = (Class<?  extends  HiveAuthorizationProvider>)configClass;
       }
       if  (cls !=  null ) {
         ret = ReflectionUtils.newInstance(cls, conf);
       }
     catch  (Exception e) {
       throw  new  HiveException(e);
     }
     ret.setAuthenticator(authenticator);
     return  ret;
   }

如果要想返回v2,需要让设置的authorize相关类必须实现HiveAuthorizerFactory接口,且不能实现HiveAuthorizationProvider接口
反馈如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Refer to the org.apache.Hadoop.hive.ql.exec.DDLTask.roleDDL function, AuthorizationMode 
doesn't support  SHOW CURRENT ROLES statement
But AuthorizationModeV2 supports  this :
private  int  roleDDLV2(RoleDDLDesc roleDDLDesc)  throws  HiveException, IOException {
…….
     case  SHOW_CURRENT_ROLE:
       List<String> roleNames = authorizer.getCurrentRoleNames();
       writeListToFileAfterSort(roleNames, roleDDLDesc.getResFile());
       break ;
But by  default ,hive uses AuthorizationMode (because the  default  value of 
hive.security.authorization.manager is
org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider,
which means AuthorizationMode )
If you want to use AuthorizationModeV2,you must use another authorization  class
which  implements  the
org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory  interface
but not the 
org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider  interface
### Hive中查询账号权限信息的方法 在Hive中,账号权限信息的管理依赖于其授权机制。默认情况下,Hive使用 `org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider` 作为权限管理类,负责处理用户对数据库对象的访问控制 [^1]。要查询用户的权限信息,需要结合Hive的授权机制和底层的元数据库。 #### 使用HiveQL查询权限信息 Hive本身提供了一些系统表(如 `DBS`, `TBLS`, `COLUMNS_V2`, `ROLES`, `ROLE_MAP`, `GLOBAL_PRIVS`, `DB_PRIVS`, `TBL_PRIVS` 等)来存储数据库对象和权限信息。这些表通常位于Hive的元数据库(如MySQL、PostgreSQL等)中。 要查询用户的权限信息,可以通过访问这些系统表。例如,查询某个用户在特定数据库或表上的权限: ```sql -- 查询用户在全局层级的权限 SELECT * FROM GLOBAL_PRIVS WHERE USER_GRANT_OPTION = 'username'; -- 查询用户在数据库层级的权限 SELECT * FROM DB_PRIVS WHERE USER_GRANT_OPTION = 'username'; -- 查询用户在表层级的权限 SELECT * FROM TBL_PRIVS WHERE USER_GRANT_OPTION = 'username'; ``` 上述查询需要直接访问Hive的元数据库,而不是通过HiveQL接口。这是因为HiveQL本身并不提供直接查询权限信息的命令,权限信息的查询通常需要通过元数据库进行。 #### 使用Hive命令行工具 如果Hive配置了基于角色的访问控制(RBAC),可以通过Hive的命令行工具查询角色和用户之间的映射关系: ```sql -- 查看所有角色 SHOW ROLES; -- 查看当前用户的角色 SHOW CURRENT ROLES; -- 查看某个角色的权限 SHOW GRANT ROLE role_name; ``` 此外,还可以通过以下命令查看特定用户或角色对数据库或表的权限: ```sql -- 查看某个用户对数据库的权限 SHOW GRANT USER username ON DATABASE database_name; -- 查看某个用户对表的权限 SHOW GRANT USER username ON TABLE database_name.table_name; ``` 这些命令可以帮助用户快速了解特定账号在Hive中的权限配置。 #### 权限信息的存储结构 Hive的权限信息存储在元数据库的多个表中,包括但不限于: - `GLOBAL_PRIVS`: 存储全局权限信息。 - `DB_PRIVS`: 存储数据库层级的权限信息。 - `TBL_PRIVS`: 存储表层级的权限信息。 - `ROLE_MAP`: 存储角色与用户之间的映射关系。 - `ROLES`: 存储角色的定义。 如果Hive的元数据库是MySQL,则可以直接通过SQL查询这些表来获取权限信息。例如: ```sql -- 查询用户在数据库层级的权限 SELECT * FROM DB_PRIVS WHERE principal_name = 'username'; ``` #### 总结 Hive的权限管理依赖于其授权机制和元数据库的存储结构。通过HiveQL命令和直接访问元数据库,可以查询用户在不同层级(全局、数据库、表)的权限信息。需要注意的是,Hive的权限查询功能有限,通常需要结合元数据库进行更详细的权限分析。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值