概述
目录
前言
一、提出问题:beeline登录后没有认证
二、hiveServer2的身份认证
1.自定义hiveServer2身份认证
2.测试一下
三、hive.server2.enable.doAs配置
总结
前言
我的上一篇文章探讨了用户及库表权限,文章最后也抛出一个安全隐患,即用beeline访问hiveserver2时仍然出现任意用户可以随意操作hive集群的情况。
本文目标是:用beeline访问可以进行身份认证,并且登录的用户有权限认证。以下是正文。
一、提出问题:beeline登录后没有认证
什么是HiveServer2?
官网解释:HiveServer2(HS2)是一个服务端接口,使远程客户端可以执行对Hive的查询并返回结果。目前基于Thrift RPC的实现是HiveServer的改进版本,并支持多客户端并发和身份验证。
据官网解释,hiveserver2是有身份验证的。beeline是HiveServer2的客户端,但我在上一篇文章设置了用户权限后,用beeline以下命令却能访问任意库表,这就引出了对hiveServer2身份认证的思考。
beeline -u jdbc:hive2://192.168.0.25:10000/default -n cln
另外还要探究一个问题,进行hiveServe2身份认证后就可以以登录用户作为hive的执行用户吗?
二、hiveServer2的身份认证
HiveServer2身份认证对应的hive属性为hive.server2.authentication,该属性有6个参数,分别是:
- NONE: 不进行身份验证检查-普通的SASL传输。任何登录者都拥有超级权限,可以对hive进行任意操作。
- LDAP: 基于LDAP/AD身份认证。
- KERBEROS: Kerberos/GSSAPI 认证。
- CUSTOM: 自定义身份验证提供程序(与hive.server2.custom.authentication.class一起使用)
- PAM: 可插拔认证模块。
- NOSASL: 原始传输。需要任意一个用户名,不需要密码,不填写或者填写错误用户名会导致报错。
下面我们以CUSTOM认证来自定义认证逻辑:通过提前约定好的文件hive.server2.users.conf,对用户输入的用户和密码进行校验(代码参考网上的示例)。
1.自定义hiveServer2身份认证
package com.costome.hs2.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 user, 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");
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(user) && 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 [" + user + "] auth check ok .. ");
} else {
System.out.println("user [" + user + "] auth check fail .. ");
throw new AuthenticationException("user [" + user + "] auth check fail .. ");
}
}
//MD5加密
static 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);
}
}
}
上面项目如果是maven项目,下面是依赖的pom.xml(hive和hadoop的版本要与集群的匹配):
<?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>com.costome.hs2</groupId>
<artifactId>auth</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-common</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<artifactId>hadoop-annotations</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-api</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-server-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-server-resourcemanager</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<artifactId>hadoop-auth</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-client</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-hdfs</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-api</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
<exclusion>
<artifactId>hadoop-yarn-common</artifactId>
<groupId>org.apache.hadoop</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-server-resourcemanager</artifactId>
<version>2.7.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
项目编译没问题后,执行以下操作:
1)将上面的程序打包成HiveServer2Auth.jar,放到$HIVE_HOME/lib下,
2)在hive-site.xml中设置以下参数:
<property>
<name>hive.server2.authentication</name>
<value>CUSTOM</value>
</property>
<property>
<name>hive.server2.custom.authentication.class</name>
<value>com.costome.hs2.auth.CustomHiveServer2Auth</value>
</property>
<property>
<name>hive.server2.custom.authentication.file</name>
<value>/export/hive/conf/hive.server2.users.conf</value>
</property>
3)在件/export/hive/conf/新建文件hive.server2.users.conf,里面内容如下:
cln,dcddb75469b4b4875094e14561e573d8(此md5值为00000通过上面md5方法算出的)
admin,dcddb75469b4b4875094e14561e573d8
4)重启hiveserver2
2.测试一下
操作完成用beelline来测试下(测试时用beeline -u jdbcURL -n user指定用户的方式不行,只能通过下面这种方面才可以):
[hdfs@v0106-c0a8003a lib]$ beeline
beeline> !connect jdbc:hive2://192.168.0.25:10000/default
Connecting to jdbc:hive2://192.168.0.25:10000/default
Enter username for jdbc:hive2://192.168.0.25:10000/default: cln
Enter password for jdbc:hive2://192.168.0.25:10000/default: *****
0: jdbc:hive2://192.168.0.25:10000/default> select current_user();
+-------+--+
| _c0 |
+-------+--+
| hdfs |
+-------+--+
以上测试结果显示:
1)身份认证成功了吗?必须输入用户名(cln)密码(00000)登录且用户名或密码正确才可以操作hive,说明身份认证已经成功!(用户名和密码是从上面设置的hive.server2.users.conf文件中读取的)
2)登录用户是hive执行用户吗?通过select current_user()发现仍然是hdfs用户,说明没有成功。
继续研究其他配置,发现了doAs。
三、hive.server2.enable.doAs配置
hive.server2.enable.doAs设置为false,则会以起hiveServer2 daemon的admin user来执行语句,示例中为hdfs;设置为true,hiveServer2会以提交用户的身份去执行语句。
我们此doAs设置为true,在hive-site.xml中设置以下参数:
<property>
<name>hive.server2.enable.doAs</name>
<value>true</value>
</property>
重启hiveserver2,再测试:
省略beeline语句…………
0: jdbc:hive2://192.168.0.25:10000/default> select current_user();
+-------------+--+
|
_c0
|
+-------------+--+
| cln
|
+-------------+--+
1 row selected (1.868 seconds)
再次测试当前用户已经不再是超级用户hdfs,变成了登录用户,目标达到,实验成功!
基它思考:在测试时注意到hive.server2.proxy.user这个属性,效果与上面一样。执行命令:beeline -u"jdbc:hive2://192.168.0.25:10000/default;hive.server2.proxy.user=cln",也可以通过代理用户cln访问该用户有权限的表。这个属性做什么用,后面遇到再深入探讨吧。
总结
上面探讨hiveServer身份认证方式并以自定义方式为例做了测试。得出hiveServer2身份认证只是用作身份认证并不会以该身份/用户进行yarn提交,想要以登录用户作为hive的执行用户还要结合doAs配置完成。
最后
以上就是眯眯眼手链为你收集整理的探索Hive用户权限(二):HiveServer2安全访问Hive前言一、提出问题:beeline登录后没有认证二、hiveServer2的身份认证三、hive.server2.enable.doAs配置总结的全部内容,希望文章能够帮你解决探索Hive用户权限(二):HiveServer2安全访问Hive前言一、提出问题:beeline登录后没有认证二、hiveServer2的身份认证三、hive.server2.enable.doAs配置总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复