自定义HiveServer2的用户安全认证

4 篇文章 0 订阅
2 篇文章 0 订阅

HiveServer2提供了JDBC链接操作Hive的功能,非常实用,但如果在使用HiveServer2时候,不注意安全控制,将非常危险,因为任何人都可以作为超级用户来操作Hive及HDFS数据。

比如:在配置HiveServer2的时候,hive.server2.authentication=NONE,表示没有用户认证。


使用beeline,模拟成超级用户hadoop,成功连接到HiveServer2.

创建数据库lxw1234;

0: jdbc:hive2://localhost:10000> create database lxw1234;

No rows affected (0.157 seconds)

0: jdbc:hive2://localhost:10000>


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根目录的写权限:


因此,如果使用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.ys.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  {
    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).toUpperCase();
        }
    }
    public static void main(String[] args) {
    	CustomHiveServer2Auth.MD5 md5 = new CustomHiveServer2Auth().new MD5();
    	System.out.println(md5.md5("root"));
	}
}
 
	

将上面的程序打包成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连接:


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


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

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


日志中打印出user [lxw1234] auth check ok ..

同样,已经配置过的user用户密码password也可以正常连接:


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


 

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

 


 

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

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


转自:https://www.cnblogs.com/1130136248wlxk/articles/5519285.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值