可以通过直线连接到配置单元,但不能连接到java。错误无法使用JDBC打开客户端传输Uri GSS启动失败
问题描述:
我对启用了kerberos的远程hdfs集群具有访问权限。当我尝试使用直线连接时可以通过直线连接到配置单元,但不能连接到java。错误无法使用JDBC打开客户端传输Uri GSS启动失败
beeline -u "jdbc:hive2://host:port/arstel;principal=principal"
连接成功。
但是,当我写一个Java应用程序,并使用相同的JDBC开放的,我得到
ERROR transport.TSaslTransport: SASL negotiation failure
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
Caused by: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
jdbc.HiveConnection: Could not open client transport with JDBC Uri: jdbc:hive2://host:port/arstel;principal=principal
Exception in thread "main" java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://host:port/arstel;principal=principal: GSS initiate failed
Caused by: org.apache.thrift.transport.TTransportException: GSS initiate failed
我的应用程序
public class RecordController {
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Class.forName(driverName);
Connection con = DriverManager
.getConnection("jdbc:hive2://host:port/arstel;principal=principal");
Statement stmt = con.createStatement();
String tableName = "evkuzmin_testHiveDriverTable";
stmt.execute("drop table if exists " + tableName);
stmt.execute("create table " + tableName + " (key int, value string)");
}
}
为什么会发生这种情况,我怎么能解决呢?
我也试过这个。同样的结果。
getConnection("jdbc:hive2://host:port/arstel;principal=principal;" +
"auth=kerberos;" +
"kerberosAuthType=fromSubject");
编辑
我没有密钥表。在阅读了堆栈和here后,我创建了一个指令。然后,我添加属性,以我的Java文件,这样
Class.forName(driverName);
System.setProperty("java.security.auth.login.config","gss-jaas.conf");
System.setProperty("sun.security.jgss.debug","true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
System.setProperty("java.security.krb5.conf","krb5.conf");
后,我加入到resources
GSS-的Jaas.conf
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule=required
useKeyTab=true
useTicketCache=false
principal="hive/[email protected]"
doNotPrompt=true
keyTab="EvKuzmin.keytab"
debug=true;
}
和krb5.conf的
[libdefaults]
renew_lifetime = 7d
forwardable = true
default_realm = DOMAIN
ticket_lifetime = 24h
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
DOMAIN = {
admin_server = ms-dcs.DOMAIN
kdc = ms-dcs.DOMAIN
}
[domain_realm]
.DOMAIN = DOMAIN
DOMAIN = DOMAIN
然后错误改变了
java.sql.SQLException: Could not create secure connection to jdbc:hive2://host:port/arstel;principal=hive/principal;auth=kerberos;kerberosAuthType=fromSubject: Failed to open client transport
Caused by: javax.security.sasl.SaslException: Failed to open client transport [Caused by java.io.IOException: Could not instantiate SASL transport]
Caused by: java.io.IOException: Could not instantiate SASL transport
Caused by: javax.security.sasl.SaslException: Failure to initialize security context [Caused by GSSException: Invalid name provided (Mechanism level: Cannot locate default realm)]
Caused by: GSSException: Invalid name provided (Mechanism level: Cannot locate default realm)
ALSO
有alrady这里密钥表
Keytab name: FILE:/etc/krb5.keytab
但我不知道什么是它的领域或如何使用它+我没有访问该文件夹。
EDIT2 2017-08-09
尝试通过UserGroupInformation进行操作。遇到错误
Exception in thread "main" java.lang.IllegalArgumentException: Invalid attribute value for hadoop.security.authentication of Kerberos
at org.apache.hadoop.security.UserGroupInformation.initialize(UserGroupInformation.java:200)
at org.apache.hadoop.security.UserGroupInformation.setConfiguration(UserGroupInformation.java:227)
at com.hive.connect.controller.RecordController.main(RecordController.java:20)
EDIT3 2017年8月10日 使用用户组
public class RecordController {
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException, ClassNotFoundException, IOException {
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication", "kerberos");
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab("hive/principal", "EvKuzmin.keytab");
Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager
.getConnection("jdbc:hive2://host:port/arstel;" +
"principal=hive/principal;" +
"tez.queue.name=adhoc;" +
"hive.execution.engine=tez;" +
"mapreduce.job.reduces=1;");
错误
java.io.IOException: Login failure for hive/principal from keytab EvKuzmin.keytab
at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:695)
at com.hive.connect.controller.RecordController.main(RecordController.java:22)
Caused by: javax.security.auth.login.LoginException: Unable to obtain password from user
答
最后,我改变了我的krb5。CONF看起来像这样
[libdefaults]
renew_lifetime = 7d
forwardable = true
default_realm = DOMAIN
ticket_lifetime = 24h
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
DOMAIN = {
admin_server = ms-dcs.DOMAIN
kdc = ms-dcs.DOMAIN
}
[domain_realm]
.DOMAIN = DOMAIN
DOMAIN = DOMAIN
我的Java代码
public class RecordController {
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException, ClassNotFoundException, IOException {
Class.forName(driverName);
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
System.setProperty("java.security.krb5.conf","krb5.conf");
Connection con = DriverManager
.getConnection("jdbc:hive2://host:port/arstel;" +
"principal=hive/[email protected];" +
"auth=kerberos;" +
"kerberosAuthType=fromSubject");
编辑
当我启动群集我不需要输入密码和登录,而是在本地机器上我做的窗户。
您是否创建了一个keytab?你在什么配置文件中指定它? –
使用'UserGroupInformation'类使用keytab登录。 – philantrovert
@T更新了我的文章。 – Evgenii