HiverServer2支持远程多客户端的并发和认证,支持通过JDBC、Beeline等连接操作,是一个比较方便并且安全的方式。
但是自己的开发集群上面为了方便开发都是做了不做权限监控的设定,即设定
hive.security.authorization.enabled
false
enable or disable the Hive client authorization
这样在使用hiveserver2连接的时候无论你输不输入用户名密码,都会正常进入,并且能进行各种操作。
但是这个明显是不安全的,毕竟正常情况下,如何设定需要校验用户登录呢,修改hive-site.xml中代码:
hive.security.authorization.enabled
false
enable or disable the Hive client authorization
hive.server2.thrift.client.user
用户名
Username to use against thrift client
hive.server2.thrift.client.password
用户名密码
Password to use against thrift client
这样,就可以用设定的用户名密码进行登录了。
但是,现在我需要做的是一个hive的开放平台,多用户管理。
这种方式并不适用。
现有几种种方式:
1、采用PAM的模式
2、采用kerberos验证
3、自定义验证
现在使用hive的自定义验证:
编写用户权限验证的类:
需要实现org.apache.hive.service.auth.PasswdAuthenticationProvider接口,
代码如下:这里直接引用了https://www.cnblogs.com/1130136248wlxk/articles/5519285.html
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);
}
}
}
打包,上传至HIVE_HOME下的lib中。
然后修改配置:
hive.server2.authentication
CUSTOM
hive.server2.custom.authentication.class
自己编写的类的引用路径
hive.server2.custom.authentication.file
校验文本的路径
然后,校验文本的格式是
用户名,密码的md5加密
很重要的一点,core-site.xml中必须设定该登录用户拥有冒用hdfs用户的权限,为方便起见,此处不做校验,直接设定任意用户都可冒用.
hadoop.proxyuser.hdfs.users
*
Allow the superuser adorechen to impersonate users of hadoop, hive, anonymous
以及该登录用户需要在/user/hive/warehouse和/tmp拥有读写的权限.
这样便可以在连接hiveserver2时进行用户校验了
此处的用户名密码校验文本是存储在文档中的,它也可以存储在关系型数据库中,还没有测试过,就暂时不放出来了。
此文仅仅是做了登录管理,对hive中的权限管理下次再写