Я попытался сгенерировать токен, который можно использовать в качестве заголовка HTTP для аутентификации по URL-адресу HDFS WebHDFS и URL-адресу Oozie REST API. Я сослался на приведенный ниже URL-адрес, чтобы получить приведенный ниже код для создания токена Negotiate. https://www.ibm.com/support/knowledgecenter/en/SS7JFU_8.5.5/com.ibm.websphere.express.doc/ae/tsec_SPNEGO_token.html
public class TokenCreation {
private static final String SPNEGO_OID = "1.3.6.1.5.5.2";
private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
public static byte[] genToken(String principal) {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
byte[] spnegoToken = new byte[0];
try {
Oid spnegoMechOid = new Oid(SPNEGO_OID);
Oid krb5MechOid = new Oid(KERBEROS_OID);
GSSCredential clientGssCreds = null;
GSSManager manager = GSSManager.getInstance();
GSSName gssUserName = manager.createName(principal, GSSName.NT_USER_NAME, krb5MechOid);
clientGssCreds = manager.createCredential(gssUserName.canonicalize(krb5MechOid),
GSSCredential.INDEFINITE_LIFETIME,
krb5MechOid,
GSSCredential.INITIATE_ONLY);
clientGssCreds.add(gssUserName,
GSSCredential.INDEFINITE_LIFETIME,
GSSCredential.INDEFINITE_LIFETIME,
spnegoMechOid, GSSCredential.INITIATE_ONLY);
GSSName gssServerName = manager.createName(principal, GSSName.NT_USER_NAME);
GSSContext clientContext = manager.createContext(gssServerName.canonicalize(spnegoMechOid),
spnegoMechOid,
clientGssCreds,
GSSContext.DEFAULT_LIFETIME);
// optional enable GSS credential delegation
clientContext.requestCredDeleg(true);
// create a SPNEGO token for the target server
spnegoToken = clientContext.initSecContext(spnegoToken, 0, spnegoToken.length);
} catch (GSSException e) {
e.printStackTrace();
}
return spnegoToken;
}
Но после запуска приведенного выше кода я всегда получал следующее приглашение:
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.c.u.security.KrbUtils - after loginUserFromKeytab............AtoimcUser:HTTP/[email protected]
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>User Name is HTTP/[email protected]
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>Mode is KERBEROS
>>>KinitOptions cache name is /tmp/krb5cc_0
Kerberos username [root]: ^C^C^C
Kerberos password for root:
Вы можете увидеть в конце приведенного выше журнала вывода. «Имя пользователя Kerberos» всегда запрашивается для запроса имени пользователя.
Также я попытался вручную запустить kinit keytab. и вышеприведенный класс может успешно сгенерировать токен. Но запускать kinit вручную НЕ так, как я хотел.
Не могли бы вы помочь? Спасибо.
UserGroupInformation
использует пользовательскую библиотеку, которая (частично) переопределяет стандартную Java-реализацию Kerberos (внутри JAAS) по ряду хороших и плохих причин (обе реализации ограничены, ненадежны и трудны для отладки) — и когда вы используете UGI для входа из keytab всегда создает частный билет, который не помещается в кеш билетов. Следовательно, вы не можете использовать его из JAAS. - person Samson Scharfrichter   schedule 25.09.2019-Dsun.security.krb5.debug=true
и-Djava.security.debug=gssloginconfig,configfile,configparser,logincontext
›› вывод НЕ красивый, как вы можете ожидать от криптографической библиотеки... - person Samson Scharfrichter   schedule 25.09.2019-Dsun.security.spnego.debug=true
при использовании собственного HTTP-клиента - person Samson Scharfrichter   schedule 25.09.2019