2
String driverName = "com.cloudera.hive.jdbc4.HS2Driver";
conf.set("hadoop.security.authentication", "kerberos");
info("Getting Connection"); 
UserGroupInformation.setConfiguration(conf);    
info("Getting Connection"); `info("Getting Connection");
UserGroupInformation.setConfiguration(conf);


UserGroupInformation.loginUserFromKeytab("****@***.***.COM","etc/****.keytab");
Class.forName(driverName); info("Getting Connection");
Connection con = DriverManager.getConnection("jdbc:hive2://localhost:10000;AuthMech=1;KrbRealm=EX‌​AMPLE.COM;KrbHostFQDN=hs2.example.com;KrbServiceName=hive");
info("Got Connection");
18:47:51,894 ERROR [1] Error in section Run at line unknown. An unexpected exception occurred in the script. Script section: Run. Caused by: LoginException occured. Unable to obtain Princpal Name for authentication 
java.sql.SQLException: [Simba][HiveJDBCDriver](500164) Error initialized or created transport for authentication: CONN_KERBEROS_AUTHENTICATION_ERROR_GET_TICKETCACHE.
    at com.cloudera.hive.hivecommon.api.HiveServer2ClientFactory.createTransport(Unknown Source)
    at com.cloudera.hive.hive.api.ExtendedHS2Factory.createClient(Unknown Source)
    at com.cloudera.hive.hivecommon.core.HiveJDBCConnection.connect(Unknown Source)
    at com.cloudera.hive.jdbc.common.BaseConnectionFactory.doConnect(Unknown Source)
    at com.cloudera.hive.jdbc.common.AbstractDriver.connect(Unknown Source)
    at java.sql.DriverManager.getConnection(DriverManager.java:582)
    at java.sql.DriverManager.getConnection(DriverManager.java:207)
    at script.run(script.java:85)
    at oracle.oats.scripting.modules.basic.api.IteratingVUser.run(IteratingVUser.java:351)
    at oracle.oats.scripting.modules.basic.api.internal.IteratingAgent.run(IteratingAgent.java:801)
Caused by: com.cloudera.hive.support.exceptions.GeneralException: [Simba][HiveJDBCDriver](500164) Error initialized or created transport for authentication: CONN_KERBEROS_AUTHENTICATION_ERROR_GET_TICKETCACHE.
    ... 10 more
Caused by: com.cloudera.hive.support.exceptions.GeneralException: CONN_KERBEROS_AUTHENTICATION_ERROR_GET_TICKETCACHE
    ... 10 more
Caused by: javax.security.auth.login.LoginException: Unable to obtain Princpal Name for authentication 
    at com.sun.security.auth.module.Krb5LoginModule.promptForName(Krb5LoginModule.java:733)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:629)
    at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
    at javax.security.auth.login.LoginContext$5.run(LoginContext.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokeCreatorPriv(LoginContext.java:703)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:575)
    at com.cloudera.hive.jdbc.kerberos.Kerberos.getSubjectViaTicketCache(Unknown Source)
    at com.cloudera.hive.hivecommon.api.HiveServer2ClientFactory.createTransport(Unknown Source)
    at com.cloudera.hive.hive.api.ExtendedHS2Factory.createClient(Unknown Source)
    at com.cloudera.hive.hivecommon.core.HiveJDBCConnection.connect(Unknown Source)
    at com.cloudera.hive.jdbc.common.BaseConnectionFactory.doConnect(Unknown Source)
    at com.cloudera.hive.jdbc.common.AbstractDriver.connect(Unknown Source)
    at java.sql.DriverManager.getConnection(DriverManager.java:582)
    at java.sql.DriverManager.getConnection(DriverManager.java:207)
    at script.run(script.java:85)
    at oracle.oats.scripting.modules.basic.api.IteratingVUser.run(IteratingVUser.java:351)
    at oracle.oats.scripting.modules.basic.api.internal.IteratingAgent.run(IteratingAgent.java:801)
    at java.lang.Thread.run(Thread.java:619)
Codebling
  • 10,764
  • 2
  • 38
  • 66
user6678264
  • 23
  • 1
  • 5

1 Answers1

2

Hive JDBC drivers don't use the Hadoop Auth libraries, because they are supposed to be able to connect from outside the cluster, with minimal dependencies on Hadoop libs.
So, in practise, your UGI settings are ignored.

But Hive JDBC drivers use the Thrift client libraries, which support raw JAAS configuration for Kerberos auth.

Sample use of system props on command-line:

java -Djava.security.krb5.conf=/etc/krb5.conf \
     -Djava.security.auth.login.config=./my_jaas.conf \
     *****

Sample "my_jaas.conf" to get a private Kerberos ticket (not read from cache, not written to cache) with a password provided in a keytab file:

com.sun.security.jgss.krb5.initiate {
  com.sun.security.auth.module.Krb5LoginModule
    required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:/some/path/to/my_login.keytab"
  principal="my_login@MY.REALM"
  debug=true;
};

Note that the syntax above works with Sun/Oracle JDK and with OpenJDK, but not with IBM JDK which uses a different syntax...
It will not work either with the DataDirect connector (shipped with Oracle, IBM, Microstrategy etc.) which expects a specific "subject" in the conf.

And that's it. The JDBC driver will automatically invoke JAAS when it detects that the URL requests a Kerberos connection, and JAAS will handle the dirty work.

PS: debugging security configuration issues is a hassle, but you have a couple of properties to enable the debug traces:

-Dsun.security.krb5.debug=true
-Djava.security.debug=gssloginconfig,configfile,configparser,logincontext
Samson Scharfrichter
  • 8,884
  • 1
  • 17
  • 36
  • Please provide a complete information since I am new to HIVE. The above answer is helpful but could you please provide the detail how the program will lokk like. – user6678264 Aug 08 '16 at 04:59
  • 3
    Look, dude, this is not a charity where experienced people agree to give free tutorship to dummies. Do your homework => spend some time on Google, experiment with Java code. – Samson Scharfrichter Aug 08 '16 at 08:05
  • And in case you are really a dummy, the part where I say *"...And that's it. The JDBC driver will automatically invoke JAAS when it detects that the URL requests a Kerberos connection, and JAAS will handle the dirty work..."* really means that. You just need `Connection con = DriverManager.getConnection(urlWithExplicitKerberosInvocation);` – Samson Scharfrichter Aug 08 '16 at 08:08
  • This is good info. However using debug I get >>>KinitOptions cache name is /tmp/krb5cc_0 java.sql.SQLException: [Cloudera][HiveJDBCDriver](500168) Error creating login context using ticket cache: Unable to obtain Principal Name for authentication . But klist shows Ticket cache: KCM:0 not FILE:/tmp/krb5cc_0 . Therefore it fails to get the hive connection due to cache mismatch. On different server Ticket cache is: FILE:/tmp/krb5cc_0 the java code works fine to connect to hive. How do I make KCM cache into FILE cache in kinit? Since the java code wants to read ccache and not jaas.conf keytab. – ebeb Aug 26 '21 at 22:31
  • 1
    The Java implementation of Kerberos has some limitations; the Hadoop-Auth library adds some more. AFAIK you **must** use a ticket cache of type `FILE:` -- in-memory cache services won't work https://web.mit.edu/kerberos/www/krb5-latest/doc/basic/ccache_def.html#ccache-types – Samson Scharfrichter Aug 26 '21 at 22:31
  • bingo! you are a genius even after 5 years :) . Commented out KCM in the file /etc/krb5.conf.d/kcm_default_ccache and did kinit again shows Ticket cache: FILE:/tmp/krb5cc_0 . Immediately the java code worked and now dont even need jaas.conf just need driver HiveJDBC41.jar which probably means the DriverManager.getConnection("jdbc:hive2://....) reads the kerberos ticket from the FILE: ccache and not jaas.conf. – ebeb Aug 26 '21 at 22:55
  • JAAS conf has hard-coded defaults (depending on OS), with several things to try in cascade, and the last thing to try is... the OS-level cache. Not necessarily the default cache BTW, can be overriden via `$KRB5CCNAME` if you want "private" tickets _(e.g. when the same user runs different jobs with different creds)_ – Samson Scharfrichter Aug 27 '21 at 00:39