我正在尝试编写一个程序,使用带有Kerberos身份验证的Jdbc驱动程序连接到Hive。我的程序如下:
public static void main(String a[])
{
...
connectionString_ = "jdbc:hive2://cdh-542-kerberos.domain.com:10000/default;principal=hive/cdh-542-kerberos.domain.com@REALMDOMAIN";
UserGroupInformation ugi = createUgi();
connection = ugi.doAs(new PrivilegedExceptionAction<Connection>() {
public Connection run() throws Exception {
Connection connection = null;
Class.forName(jdbcDriverClass_);
connection = DriverManager.getConnection(connectionString_);
return connection;
}
});
...
}
public static UserGroupInformation createUgi()
{
try{
UserGroupInformation ugi = null;
String principal = "hive/cdh-542-kerberos.domain.com@REALMDOMAIN"
String keyTabLocation = "hive.keytab"
logger.debug("principal:" + principal);
logger.debug("keyTabLocation:" + keyTabLocation);
ugi = createkerbUser( principal, keyTabLocation);
return ugi;
}
catch(Exception e)
{
throw new BDEToolSecurityException(BDEToolSecurityException.SECURITYEXCPETION, e);
}
}
public static UserGroupInformation createkerbUser( String principal, String keyTabFilePath)
{
UserGroupInformation app_ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keyTabFilePath);
String user = getUserfromPrincipal(principal);
if(user.trim().length() > 0){
UserGroupInformation proxy_ugi = UserGroupInformation.createProxyUser(user, app_ugi);
return proxy_ugi;
}
return app_ugi;
}
private static String getUserfromPrincipal(String principal)
{
String user = Constants.emptyString;
if(principal.contains(Constants.fSlash)){
String[] tokens = principal.split(Constants.fSlash);
if(tokens.length > 1){
user = tokens[0];
}
}
return user;
}
当尝试使用ugi.doAs()...以及异常
时,此代码失败java.sql.SQLException:无法使用JDBC Uri打开客户端传输:jdbc:hive2://cdh-542-kerberos.informatica.com:10000 / default; principal = hive / cdh-542-kerberos.informatica。 com @ INFAQAKERB:GSS发起失败 在org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:215) 在org.apache.hive.jdbc.HiveConnection。(HiveConnection.java:163) 在org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105) 在java.sql.DriverManager.getConnection(DriverManager.java:571) 在java.sql.DriverManager.getConnection(DriverManager.java:233) 在com.informatica.gcs.tools.bde.connectivity.tool.hive.HiveJdbcTest $ 1.run(HiveJdbcTest.java:148) 在com.informatica.gcs.tools.bde.connectivity.tool.hive.HiveJdbcTest $ 1.run(HiveJdbcTest.java:144) at java.security.AccessController.doPrivileged(Native Method) 在javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1671) ......还有6个 引起:org.apache.thrift.transport.TTransportException:GSS启动失败 在org.apache.thrift.transport.TSaslTransport.sendAndThrowMessage(TSaslTransport.java:232) 在org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:316) at org.apache.thrift.transport.TSaslClientTransport.open(TSaslClientTransport.java:37) 在org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport $ 1.run(TUGIAssumingTransport.java:52) 在org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport $ 1.run(TUGIAssumingTransport.java:49) at java.security.AccessController.doPrivileged(Native Method) 在javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1671) 在org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport.open(TUGIAssumingTransport.java:49) 在org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:190) ......还有15个
keytab和princiapl似乎都是正确的。我可以成功运行命令
kinit -k -t hive.keytab hive/cdh-542-kerberos.informatica.com@INFAQAKERB
有人可以帮我进一步解决这个问题。我在这个问题上被困了将近一个星期。如果需要,我可以提供其他信息。
答案 0 :(得分:0)
这不是丢失/过期的机票问题。否则错误堆栈将在“GSS启动失败”后立即读取“由GSS异常引起:没有提供有效凭证”。
可能出现的问题:
您尝试连接的服务器(Hive Server 2,端口10000)和客户端计算机(使jdbc:hive连接)似乎位于不同的域中。是这样的吗?
要确认您的服务器和客户端可以在该域中进行身份验证,并且其域配置正确(krb5.conf等),请执行
$ kinit -k -t hive.keytab hive/cdh-542-kerberos.informatica.com@INFAQAKERB (like you did)
$ klist
“org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:215)”可以提示它可能是从HS2服务器到域控制器服务器的防火墙/域配置问题。虽然您可以在客户端创建票证,但HS2服务器无法对其进行验证。
在您的代码段中 - 查看Examples of connecting to Kerberos Hive in JDBC。
您的代码似乎至少缺失:
UserGroupInformation.setConfiguration(conf);
不确定它是否与您的用例相关......
如果您能够解决此问题,请及时通知我们。
答案 1 :(得分:0)
对于配置单元,您不应该使用proxyuser来执行ugi.doAs。将代码修改为
public static UserGroupInformation createkerbUser( String principal, String keyTabFilePath)
{
return UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keyTabFilePath);
}
OR
public static UserGroupInformation createkerbUser( String principal, String keyTabFilePath)
{
UserGroupInformation.loginUserFromKeytab(principal, keyTabFilePath);
return UserGroupInformation.getLoginUser();
}
如果您需要进行模拟,请附加
hive.server2.proxy.user =
<proxyUser>
(对于apache驱动程序)到JDBC连接字符串。
PS:在群集配置中,如果您计划使用“代理用户”属性,则hive用户应具有模拟其他用户的权限。