Ошибка генерации токена SPNEGO - PullRequest
       129

Ошибка генерации токена SPNEGO

0 голосов
/ 25 сентября 2019

Я попытался сгенерировать токен, который можно использовать в качестве заголовка HTTP для аутентификации по URL-адресу HDFS WebHDFS и URL-адресу Oozie REST API.Я ссылался на приведенный ниже URL, чтобы иметь приведенный ниже код для генерации токена согласования.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/host1.exmaple.com@EXAMPLE.COM
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>User Name is HTTP/host1.exmaple.com@EXAMPLE.COM
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 вручную НЕ тот способ, которым я хотел.

Не могли бы вы помочь?Спасибо.

1 Ответ

0 голосов
/ 26 сентября 2019

Поддержка Kerberos и SPNEGO в Java, к сожалению, громоздка.

Я создал небольшую библиотеку, чтобы упростить некоторые случаи использования Kerberos: https://github.com/bedrin/kerb4j Вы можете использовать ее для генерации токена SPNEGO:

SpnegoClient spnegoClient = SpnegoClient.loginWithKeyTab("svc_consumer", "/opt/myapp/consumer.keytab");
URL url = new URL("http://api.provider.acme.com/api/operation1");
SpnegoContext context = spnegoClient.createContext("http://provider.acme.com"); // Will result in HTTP/provider.acme.com SPN
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", context.createTokenAsAuthroizationHeader());
...