Аутентификация Kerberos от java до impala keytab с помощью конфигурации JAAS - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь подключиться к БД Impala, используя аутентификацию Kerberos KeyTab и конфигурацию JAAS.

Я уже могу подключиться к Impala DB, установив системное свойство - "java.security.auth.login.config" в файл конфигурации JAAS. И это работает отлично. Вот рабочий код:

System.setProperty("sun.security.krb5.debug", "false");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "true");
System.setProperty("java.security.krb5.conf", krb5ConfPath);
System.setProperty("java.security.auth.login.config", jaasPath);

org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
conf.set("hadoop.security.authentication", "kerberos");

UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(principal, keyTabPath);

DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(DatabaseConfig.class.getClassLoader());
return dataSourceBuilder.build();

Проблема в том, что в конфигурации JAAS требуется абсолютный путь к файлу keytab. В моем случае этот путь будет варьироваться от среды к среде, и я не хочу поддерживать разные jaas.config для каждой среды.

Итак, я выбрал программный подход для генерации конфигурации JAAS. Я могу создать объект "javax.security.auth.login.Configuration" и установить его, используя
javax.security.auth.login.Configuration.setConfiguration (jaasConfig);

Но когда я запускаю код с этим изменением, он не может выбрать конфигурацию JAAS и завершается ошибкой, за исключением следующего:

Не удалось получить соединение JDBC; вложенное исключение java.sql.SQLException: [Симба] Ошибка ImpalaJDBCDriver создание контекста входа в систему с использованием кэша билетов: невозможно получить принципал Имя для аутентификации.

Кто-нибудь может объяснить, почему код работает нормально, когда конфигурация задается через свойство System, но не работает, когда он задается программно.

System.setProperty("sun.security.krb5.debug", "false");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "true");
System.setProperty("java.security.krb5.conf", krb5ConfPath);

javax.security.auth.login.Configuration jaasConfig = createJaasConfig(keyTabPath);
             javax.security.auth.login.Configuration.setConfiguration(jaasConfig);

org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
conf.set("hadoop.security.authentication", "kerberos");

UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(principal, keyTabPath);

DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(DatabaseConfig.class.getClassLoader());
return dataSourceBuilder.build();

Вот как я создаю JAAS Config:

private static javax.security.auth.login.Configuration createJaasConfig(final String keyTabPath) throws Exception {

        // Create entry options.
        Map<String, Object> options = new HashMap<>();
        options.put("useTicketCache", "false");
        options.put("doNotPrompt", "true");
        options.put("useKeyTab", "true");
        options.put("debug", "false");
        // options.put("storeKey", "true");
        options.put("principal", "user@DOMAIN.COM");
        options.put("keyTab", keyTabPath);

        // Create entries
        AppConfigurationEntry[] entries = {
            new AppConfigurationEntry(
                Krb5LoginModule.class.getCanonicalName(),
                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
                options
            )
        };

        // Create configuration
        return new javax.security.auth.login.Configuration() {
            @Override
            public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
                return entries;
            }
        };
    }
...