我编写了一个使用 keytabs 访问 hadoop 的代码,但我希望它只使用凭据而不是 keytabs,有没有办法做到这一点?以下是我目前正在使用的代码 -
public static void loginToHDFSUsingKeytab(Configuration hdfsConf) {
hdfsConf.set("hadoop.security.authentication", "kerberos");
hdfsConf.set("dfs.namenode.kerberos.principal", nameNodePrincipal);
UserGroupInformation.setConfiguration(hdfsConf);
try {
UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(loginUser, keytab);
UserGroupInformation.setLoginUser(ugi);
System.out.println("Logged in successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
我遇到几个线程说有一种方法叫做
UserGroupInformation.loginUserFromSubject(主题)
但我在 UserGroupInformation 类中看不到该方法。我尝试了 2.2.0 和 3.1.1 版本的 hadoop-commons,但是这两种方法都不可用。
更新 :
我尝试使用 JAAS 和以下代码进行身份验证:
public static void main(String args[]) throws Exception {
System.setProperty("kerberos.security.enabled", "true");
System.setProperty("java.security.auth.login.config", jaasFilePath);
// System.setProperty("javax.security.auth.login.name", loginUser);
// System.setProperty("javax.security.auth.login.password", password);
Configuration conf = new Configuration();
conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
conf.set("hadoop.security.authentication", "kerberos");
conf.set("dfs.namenode.kerberos.principal", nameNodePrincipal);
loginWithPassword(activeNamenodeURI, conf);
// usingKeytabs(conf);
}
private static void loginWithPassword(final String args, final Configuration conf) throws Exception {
LoginContext loginContext = new LoginContext("com.sun.security.jgss.initiate", new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
System.out.println("inside handle method" + callback.getClass());
if (callback instanceof NameCallback) {
NameCallback nameCallback = (NameCallback) callback;
nameCallback.setName(loginUser);
} else if (callback instanceof PasswordCallback) {
System.out.println(">>>>>>>>>>>>>>> password : " + password);
PasswordCallback passwordCallback = (PasswordCallback) callback;
passwordCallback.setPassword(password.toCharArray());
} else {
System.out.println("exception ");
throw new UnsupportedCallbackException(callback);
}
}
}
});
loginContext.login();
Subject mySubject = loginContext.getSubject();
Subject.doAs(mySubject, new PrivilegedExceptionAction() {
public Object run() throws Exception {
System.out.println("inside run");
System.out.println("##################System.getProperty(\"java.security.auth.login.config\") : "
+ System.getProperty("java.security.auth.login.config"));
FileSystem fs = null;
try {
fs = FileSystem.get(new URI(activeNamenodeURI), conf);
FileStatus[] df = fs.listStatus(new Path("/"));
for (FileStatus status : df) {
System.out.println(status.getPath().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return conf;
}
});
}
JAAS 文件内容是 -
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
principal="user1@DOMAIN"
tryFirstPass=true
debug=true;
};
以下是控制台上的输出和错误 -
Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is flbuser@IMPETUS tryFirstPass is true useFirstPass is false storePass is false clearPass is false
Password from shared state is null
[Krb5LoginModule] tryFirstPass failed with:Password can not be obtained from sharedstate
inside handle methodclass javax.security.auth.callback.NameCallback
inside handle methodclass javax.security.auth.callback.PasswordCallback
>>>>>>>>>>>>>>> password : user1
[Krb5LoginModule] user entered username: user1
principal is user1@DOMAIN
Commit Succeeded
inside run
##################System.getProperty("java.security.auth.login.config") : /user/jaas.conf
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: SIMPLE authentication is not enabled. Available:[TOKEN, KERBEROS]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.hadoop.ipc.RemoteException.instantiateException(RemoteException.java:106)
at org.apache.hadoop.ipc.RemoteException.unwrapRemoteException(RemoteException.java:73)
at org.apache.hadoop.hdfs.DFSClient.listPaths(DFSClient.java:1662)
at org.apache.hadoop.hdfs.DFSClient.listPaths(DFSClient.java:1643)
at org.apache.hadoop.hdfs.DistributedFileSystem.listStatusInternal(DistributedFileSystem.java:640)
at org.apache.hadoop.hdfs.DistributedFileSystem.access$600(DistributedFileSystem.java:92)
at org.apache.hadoop.hdfs.DistributedFileSystem$14.doCall(DistributedFileSystem.java:702)
at org.apache.hadoop.hdfs.DistributedFileSystem$14.doCall(DistributedFileSystem.java:698)
at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)
at org.apache.hadoop.hdfs.DistributedFileSystem.listStatus(DistributedFileSystem.java:698)
at com.test.KerberosLogin$2.run(KerberosLogin.java:140)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at com.test.KerberosLogin.loginWithPassword(KerberosLogin.java:132)
at com.test.KerberosLogin.main(KerberosLogin.java:101)
Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): org.apache.hadoop.security.AccessControlException: SIMPLE authentication is not enabled. Available:[TOKEN, KERBEROS]
at org.apache.hadoop.ipc.Client.call(Client.java:1347)
at org.apache.hadoop.ipc.Client.call(Client.java:1300)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:206)
at com.sun.proxy.$Proxy7.getListing(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:186)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)
at com.sun.proxy.$Proxy7.getListing(Unknown Source)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getListing(ClientNamenodeProtocolTranslatorPB.java:482)
at org.apache.hadoop.hdfs.DFSClient.listPaths(DFSClient.java:1660)
... 12 more
它仍然没有工作,任何帮助将不胜感激。