Support Questions
Find answers, ask questions, and share your expertise
Announcements
Alert: Welcome to the Unified Cloudera Community. Former HCC members be sure to read and learn how to activate your account here.

Unable to use existing Subject to Authenticate Hive2 Kerberos JDBC Connection

Highlighted

Unable to use existing Subject to Authenticate Hive2 Kerberos JDBC Connection

New Contributor

Hello, I'm trying to use Subject.doAs() in java to authenticate a JDBC connection with Kerberos. I've tried following the example in Cloudera's JDBC Driver 2.5.16 documentation but have been getting "Unsupported mechanism type PLAIN".

 

java.sql.SQLException: [Simba][HiveJDBCDriver](500310) Invalid operation: Peer indicated failure: Unsupported mechanism type PLAIN;
	at com.cloudera.hive.hivecommon.api.HiveServer2ClientFactory.createTransport(HiveServer2ClientFactory.java:224)
	at com.cloudera.hive.hive.api.ExtendedHS2Factory.createClient(ExtendedHS2Factory.java:38)
	at com.cloudera.hive.hivecommon.core.HiveJDBCConnection.connect(HiveJDBCConnection.java:597)
	at com.cloudera.hive.jdbc.common.BaseConnectionFactory.doConnect(BaseConnectionFactory.java:219)
	at com.cloudera.hive.jdbc.common.AbstractDriver.connect(AbstractDriver.java:216)
	at java.sql.DriverManager.getConnection(DriverManager.java:571)
	at java.sql.DriverManager.getConnection(DriverManager.java:233)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery$AuthenticateDriverAction.run(HiveQuery.java:142)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery$AuthenticateDriverAction.run(HiveQuery.java:1)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:356)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery.MakePrivilegedClientCall(HiveQuery.java:129)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery.Execute(HiveQuery.java:77)

 

I have also tried specifying the various krb properties in the connection string which are not included in the example, but then I receive the error "Unable to obtain Princpal Name for authentication ;"

 

 

java.sql.SQLException: [Simba][HiveJDBCDriver](500310) Invalid operation: Unable to obtain Princpal Name for authentication ;
	at com.cloudera.hive.hivecommon.api.HiveServer2ClientFactory.createTransport(HiveServer2ClientFactory.java:224)
	at com.cloudera.hive.hive.api.ExtendedHS2Factory.createClient(ExtendedHS2Factory.java:38)
	at com.cloudera.hive.hivecommon.core.HiveJDBCConnection.connect(HiveJDBCConnection.java:597)
	at com.cloudera.hive.jdbc.common.BaseConnectionFactory.doConnect(BaseConnectionFactory.java:219)
	at com.cloudera.hive.jdbc.common.AbstractDriver.connect(AbstractDriver.java:216)
	at java.sql.DriverManager.getConnection(DriverManager.java:571)
	at java.sql.DriverManager.getConnection(DriverManager.java:233)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery$AuthenticateDriverAction.run(HiveQuery.java:143)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery$AuthenticateDriverAction.run(HiveQuery.java:1)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:356)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery.MakePrivilegedClientCall(HiveQuery.java:130)
	at Asci.ActiveBatch.ApacheHadoop.HiveQuery.Execute(HiveQuery.java:77)

 

 

Any ideas as to what the issue is and why the example seemingly doesn't work? I notice that the example is in the section for Windows and I am using Linux, but I imagine it should work for both. I also noticed that this example is not present in the most recent version of documentation.

 

Below is what the source code looks like...

 

private DataTable MakePrivilegedClientCall() throws Exception {
	String kdcUserName = "hive/hadoop.forumpostexample.com@KDC.COM";
	Configuration configuration = new Configuration() {
		@Override
		public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
			HashMap<String, Object> hashMap = new HashMap<String, Object>();
			hashMap.put("doNotPrompt", "false");
			hashMap.put("useTicketCache", "false");
			hashMap.put("keyTab", "/path/to/keytab");
			hashMap.put("useKeyTab", "true");
			hashMap.put("principal", "hive/hadoop.forumpostexample.com");
			return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, hashMap) };
		}
	};
	LoginContext loginContext = new LoginContext("insignificant-arbitrary-name", null, new KerberosCallbackHandler(kdcUserName, null), configuration);
	loginContext.login();

	Class.forName("com.cloudera.hive.jdbc4.HS2Driver");
	AuthenticateDriverAction authenticateAction = new AuthenticateDriverAction();
	Subject.doAs(loginContext.getSubject(), authenticateAction);
	authenticateAction.con.createStatement();
	return null;
}

public class AuthenticateDriverAction implements PrivilegedAction<Void> {
	Connection con;
	
	static final String ConnectionUrl = "jdbc:hive2://hadoop.forumpostexample.com:10000";

	/*
	 * I've also tried variations of
	 * 	static final String ConnectionUrl = "jdbc:hive2://hadoop.forumpostexample.com:10000;AuthMech=1;KrbRealm=KDC.COM;KrbHostFQDN=hadoop.forumpostexample.com;KrbServiceName=hive";
	 */

	@Override
	public Void run() {
		try {
			con = DriverManager.getConnection(ConnectionUrl);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
}

static class KerberosCallbackHandler implements CallbackHandler {
	private final String user;
	private final String password;

	public KerberosCallbackHandler(String user, String password) {
		this.user = user;
		this.password = password;
	}

	public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
		for (Callback callback : callbacks) {
			if (callback instanceof NameCallback) {
				NameCallback nc = (NameCallback) callback;
				nc.setName(user);
			} else if (callback instanceof PasswordCallback) {
				PasswordCallback pc = (PasswordCallback) callback;
				pc.setPassword(password.toCharArray());
			} else {
				throw new UnsupportedCallbackException(callback, "Unknown Callback");
			}
		}
	}
}

Also note that if I use kinit to get the approriate credentials in the cache, authentication will succeed. So it looks like even though this is inside the Subject.doAs() block, it is looking for the credentials in the cache. My main goal is to be able to use the subject's credentials. The documentation I'm referring to is at [https://www.cloudera.com/documentation/other/connectors/hive-jdbc/latest/Cloudera-JDBC-Driver-for-Ap...].

Don't have an account?
Coming from Hortonworks? Activate your account here