Kerberos не может использовать кеш билетов в коде Java

#java #kerberos #gssapi

#ява #керберос #gssapi с #java #kerberos #gssapi

Вопрос:

У меня был сервис, который пытается использовать кеш тикетов kerberos, но я всегда получаю ошибку типа Caused by: java.lang.RuntimeException: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos credentails) .

Если я не использую кэширование билетов, кажется, что все просто работает. Ниже приведены параметры, которые я использую для указания кэширования билетов.

             loginContext = new LoginContext("", null, null, new Configuration()
            {
                @Override
                public AppConfigurationEntry[] getAppConfigurationEntry(String name)
                {
                    Map<String, String> options = new HashMap<>();
                    options.put("refreshKrb5Config", "true");
                    options.put("doNotPrompt", "true");
                    if (LOG.isDebugEnabled()) {
                        options.put("debug", "true");
                    }
                    if (config.getKeytab() != null) {
                        options.put("keyTab", config.getKeytab().getAbsolutePath());
                    }
                    options.put("isInitiator", "false");
                    options.put("useKeyTab", "true");
                    options.put("principal", servicePrincipal);
                    //options.put("storeKey", "true");
                    
                    //manually specify /tmp/krb5cc_ServiceUid for ticketCache
                    options.put("ticketCache", config.getCredentialCache().getAbsolutePath());
                    options.put("useTicketCache", "true");
                    options.put("renewTGT", "true");

                    return new AppConfigurationEntry[] {new AppConfigurationEntry(Krb5LoginModule.class.getName(), REQUIRED, options)};
                }
            });
            loginContext.login();

  

Затем я использую приведенные ниже фрагменты кода, чтобы получить учетные данные:

             String name = loginContext.getSubject().getPrincipals().iterator().next().getName();
            serverCredential = doAs(loginContext.getSubject(), () -> gssManager.createCredential(
                    //gssManager.createName(config.getServiceName()   "@"   hostname, GSSName.NT_HOSTBASED_SERVICE),
                    gssManager.createName(name, GSSName.NT_HOSTBASED_SERVICE),
                    //INDEFINITE_LIFETIME,
                    DEFAULT_LIFETIME,
                    /*new Oid[] {
                            new Oid("1.2.840.113554.1.2.2"), // kerberos 5
                            new Oid("1.3.6.1.5.5.2") // spnego
                    },*/
                    new Oid("1.2.840.113554.1.2.2"),
                    ACCEPT_ONLY));
  

Есть ли что-то не так с приведенными выше фрагментами кода? Я также подтвердил, что /tmp/krb5cc_ServiceUid это действительно существует.

Спасибо

Комментарии:

1. AFAIK Java имеет только частичную реализацию Kerberos. Он может считывать TGT из кеша билетов (если конфигурация JAAS позволяет это), но не может записывать в кеш — без обновления, без создания, без повторного создания. И он никогда не использует кеш для служебных билетов.

2. Для справки, я никогда не писал код для серверной части, и я всегда передавал параметры JAAS через файл conf (синтаксис своеобразный, но как только вы понимаете, что у вас может быть несколько именованных разделов с каждым из нескольких типов аутентификации, это становится довольно легко читать …)

3. Для справки, стек Hadoop имеет свою собственную реализацию Kerberos, которая основана на Java impl, но переопределяет ряд вещей — например, он позволяет обновлять существующий TGT в кэше, выполнив kinit -R команду :-0

4. Поскольку вы не упоминаете активацию трассировок отладки, обратите внимание, что -Dsun.security.krb5.debug=true и -Djava.security.debug=gssloginconfig,configfile,configparser,logincontext создадут ОГРОМНЫЕ дампы в SdtErr / StdOut, но эти дампы могут помочь вам понять, какие параметры применяются, а какие молчаливо игнорируются (дух!)