微信搜索lxw1234bigdata | 邀请体验:数阅–数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

[一起学Hive]之二十-自定义HiveServer2的用户安全认证

Hive lxw1234@qq.com 33032℃ 6评论

关键字:hiveserver2、用户安全

HiveServer2提供了JDBC链接操作Hive的功能,非常实用,但如果在使用HiveServer2时候,不注意安全控制,将非常危险,因为任何人都可以作为超级用户来操作Hive及HDFS数据。
比如:在配置HiveServer2的时候,hive.server2.authentication=NONE,表示没有用户认证。

hiveserver2

使用beeline,模拟成超级用户hadoop,成功连接到HiveServer2.
创建数据库lxw1234;
0: jdbc:hive2://localhost:10000> create database lxw1234;
No rows affected (0.157 seconds)
0: jdbc:hive2://localhost:10000>

hiveserver2

HDFS上也是以超级用户hadoop创建的目录。
再执行drop database,同样没问题。
0: jdbc:hive2://localhost:10000> drop database lxw1234;
No rows affected (0.142 seconds)
0: jdbc:hive2://localhost:10000>

如果是以普通用户链接HiveServer2,执行创建数据库,则会报权限错误,因为普通用户没有在Hive根目录的写权限:

hiveserver2

因此,如果使用HiverServer2来提供给用户来链接Hive,必须启用安全认证,也就是hive.server2.authentication的配置。

目前HiveServer2支持多种用户安全认证方式:NONE,NOSASL, KERBEROS, LDAP, PAM ,CUSTOM等等。

本文介绍使用自定义的用户认证方式,即CUSTOM;
如果将hive.server2.authentication设置成CUSTOM,则需要设置
hive.server2.custom.authentication.class来指定用于权限认证的类,这个类需要实现
org.apache.hive.service.auth.PasswdAuthenticationProvider接口。

我们将使用HiveServer2的用户名和密码保存起来,其中,密码以32位小写md5加密来保存,这个数据即可以保存在Hive元数据库中,也可以保存在一个配置文件中。为了方便起见,这里使用配置文件来保存。

首先需要编写用户权限验证的类:

package com.lxw1234.hive.auth;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.security.sasl.AuthenticationException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;

public class CustomHiveServer2Auth implements PasswdAuthenticationProvider  {
    @Override
    public void Authenticate(String username, String password)
            throws AuthenticationException {
        
        boolean ok = false;
        String passMd5 = new MD5().md5(password);
        HiveConf hiveConf = new HiveConf();
        Configuration conf = new Configuration(hiveConf);
        String filePath = conf.get("hive.server2.custom.authentication.file");
        System.out.println("hive.server2.custom.authentication.file [" + filePath + "] ..");
        File file = new File(filePath);
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                String[] datas = tempString.split(",", -1);
                if(datas.length != 2) continue;
                //ok
                if(datas[0].equals(username) && datas[1].equals(passMd5)) {
                    ok = true;
                    break;
                }
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new AuthenticationException("read auth config file error, [" + filePath + "] ..", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {}
            }
        }
        if(ok) {
            System.out.println("user [" + username + "] auth check ok .. ");
        } else {
            System.out.println("user [" + username + "] auth check fail .. ");
            throw new AuthenticationException("user [" + username + "] auth check fail .. ");
        }
    }
    
    //MD5加密
    class MD5 {
        private MessageDigest digest;
        private char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        public MD5() {
            try {
              digest = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
              throw new RuntimeException(e);
            }
        }
        
         public String md5(String str) {
            byte[] btInput = str.getBytes();
            digest.reset();
            digest.update(btInput);
            byte[] md = digest.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char strChar[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                strChar[k++] = hexDigits[byte0 >>> 4 & 0xf];
                strChar[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(strChar);
        }
    }
    
}

将上面的程序打包成HiveServer2Auth.jar,放到$HIVE_HOME/lib下,
在hive-site.xml中设置以下参数:
<property>
<name>hive.server2.authentication</name>
<value>CUSTOM</value>
</property>
<property>
<name>hive.server2.custom.authentication.class</name>
<value>com.lxw1234.hive.auth.CustomHiveServer2Auth</value>
</property>
<property>
<name>hive.server2.custom.authentication.file</name>
<value>/usr/local/apache-hive-0.13.1-bin/conf/hive.server2.users.conf</value>
</property>

在$HIVE_HOME/conf下新建文件hive.server2.users.conf,里面写入内容:
[root@dev conf]# cat hive.server2.users.conf
lxw1234,48d9a656690e1b1bf5ddee4c12d1bbd7
user,5f4dcc3b5aa765d61d8327deb882cf99

其中,48d9a656690e1b1bf5ddee4c12d1bbd7为lxw1234_password的md5加密,
5f4dcc3b5aa765d61d8327deb882cf99为password的md5加密。

接下来,重新启动HiveServer2,使用beeline连接:

hiveserver2

再次使用hadoop用户连接,输入空密码或者不正确的密码,将不会再链接到HiveServer。

hiveserver2

HiveServer2的日志中打印出了认证失败的消息。

再试试使用用户lxw1234密码lxw1234_password连接:

hiveserver2

日志中打印出user [lxw1234] auth check ok ..
同样,已经配置过的user用户密码password也可以正常连接:

hiveserver2

使用Java JDBC连接HiveServer2,密码错误将不能正常连接:

hiveserver2

 

密码正确时才可以正常查询:

 

hiveserver2

 

这种方式做的HiveServer2用户认证,可以动态的增加、修改和删除用户及密码,只需要修改hive.server2.custom.authentication.file 配置文件即可。

当然,用户名和密码也可以保存在Hive元数据库,每次认证时候查询即可。

 

更多Hive相关的文章可查看 一起学Hive系列

您可以关注 lxw的大数据田地 ,或者 加入邮件列表 ,随时接收博客更新的通知邮件。

 

 

如果觉得本博客对您有帮助,请 赞助作者

转载请注明:lxw的大数据田地 » [一起学Hive]之二十-自定义HiveServer2的用户安全认证

喜欢 (19)
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(6)个小伙伴在吐槽
  1. 谢谢分享!很有帮助!
    leon2016-01-30 07:43 回复
  2. 我写了一个jar没成功,你的jar能共享一下吗?274285142@qq.com
    austin2016-07-27 18:47 回复
    • 怎么会不成功呢,按照文章中一步一步配置,肯定可行的啊。
      lxw1234@qq.com2016-07-28 08:03 回复
      • 好像是我的pom文件没有依赖上hadoop-common,你的pom文件发来看看吧
        austin2016-07-28 10:29 回复
  3. 按照官方提供的文档配置了,但是遇到一些问题,困扰我很久了。 https://cwiki.apache.org/confluence/display/Hive/SQL+Standard+Based+Hive+Authorization “To enable users to use functions, the ability to create permanent functions has been added. A user in the admin role can run commands to create these functions, which all users can then use. The Hive transform clause is also disabled when this authorization is enabled.” 我设置了“hive.users.in.admin.role”为austin,但是在create function 时仍然提示我没有权限 “FAILED: HiveAccessControlException Permission denied: Principal [name=austin, type=USER] does not have following privileges for operation CREATEFUNCTION [[ADMIN PRIVILEGE] on Object [type=LOCAL_URI, name=file:/home/austin/test.jar]]”
    austin2016-08-18 15:51 回复
  4. 如果结合hue的话怎么使用呢
    wenbai2018-03-30 17:39 回复