使用带Kerberos身份验证的JDBC连接到Hive的问题

问题描述:

我正在尝试使用带Kerberos身份验证的Jdbc驱动程序来编写连接到Hive的程序。我的计划是为folloows:使用带Kerberos身份验证的JDBC连接到Hive的问题

public static void main(String a[]) 
{ 

    ... 

    connectionString_ = "jdbc:hive2://cdh-542-kerberos.domain.com:10000/default;principal=hive/[email protected]"; 

    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/[email protected]" 
     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/[email protected]:GSS在org.apache.hive.jdbc启动失败 .HiveConnection.openTransport(HiveConnection.java:215) at org.apache.hive.jdbc.HiveConnection。(HiveConnection.java:163) at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105) at jav a.sql.DriverManager.getConnection(DriverManager.java:571) at java.sql.DriverManager.getConnection(DriverManager.java:233) at com.informatica.gcs.tools.bde.connectivity.tool.hive.HiveJdbcTest $ 1 .run(HiveJdbcTest.java:148) at 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) 在org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1671) ... 6个 产生的原因:组织.apache.thrift.transport.TTransportException:GSS启动失败 at org.apache.thrift.transport.TSaslTransport.sendAndThrowMessage(TSaslTransport.java:232) 在org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:316) 在org.apache.thrift.transport.TSaslClientTransport.open(TSaslClientTransport.java:37) 在org.apache.hadoop.hive。 thrift.client.TUGIAssumingTransport在org.apache.hadoop.hive.thrift.client.TUGIAssumingTransport $ 1.run(TUGIAssumingTransport.java:49)$ 1.run(TUGIAssumingTransport.java:52) 在java.security.AccessController.doPrivileged(本地方法) at javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1671) at org.apache.hadoop.hive .thrift.client.TUGIAssumingTransport.open(TUGIAssumingTransport.java:49) at org.apache.hive.jdbc.HiveConnection.o penTransport(HiveConnection.java:190) ... 15更多

keytab和princiapl似乎都是正确的。我可以成功运行命令

的kinit -k -t hive.keytab hive/[email protected]

任何人可以帮我在这。我在这个问题上陷入了将近一周的困境。如有需要,我可以提供更多信息。

+0

GSS启动失败此错误通常发生在您的kerboros票证过期时。尝试每次运行java代码时重新验证令牌。 –

+0

我已经尝试使用kninit命令重新生成票证。但没有运气。 – Fayaz

+0

您使用的是什么JVM风格? KDC预计什么样的加密? *(扰流板:默认情况下,Oracle/Sun JRE不支持AES256,您必须下载“无限强度加密”)* –

这不是缺失/过期票证问题。否则,在“GSS启动失败”之后,错误堆栈也会读取“由GSSException引起:没有提供有效的凭据”。

可能出现的问题:

  1. 看来,在那里你试图连接到(蜂巢服务器2,端口10000)和您的客户机服务器(这使得JDBC:蜂巢连接)是在不同的域。是这样吗?

  2. 要确认您的服务器和客户端可以在一个域进行验证,并且其领域的配置是否正确(krb5.conf的等),做

    $ kinit -k -t hive.keytab hive/[email protected] (like you did) 
    $ klist 
    
    • 做这在服务器和客户端并在这里复制粘贴结果。
  3. “org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:215)”可以提供一个线索,这可能是从HS2服务器防火墙/域配置问题域控制器服务器。尽管您可以在客户端创建票证,但HS2服务器无法验证它。

  4. 在你的代码片段 - 检查出Examples of connecting to Kerberos Hive in JDBC

    看来你的代码是至少丢失:

    UserGroupInformation.setConfiguration(conf); 
    

    不知道但如果它是相关的你的使用情况......

保持我们更新,如果你能解决这个。

对于配置单元,您不应该使用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:在集群配置中,如果您计划使用“代理用户”属性,则配置单元用户应具有模仿不同用户的权限。