Доступ к защищенной Kerberos WebHDFS без SPnego

У меня есть рабочее приложение для управления HDFS с помощью WebHDFS. Мне нужно иметь возможность сделать это в защищенном кластере Kerberos.

Проблема в том, что нет библиотеки или расширения для согласования билета для моего приложения, у меня есть только базовый HTTP-клиент.

Можно ли создать службу Java, которая будет обрабатывать обмен билетами и, как только он получит билет службы, просто передать его приложению для использования в HTTP-запросе? Другими словами, мое приложение попросит службу Java согласовать билеты, и оно вернет билет службы обратно в мое приложение в виде строки или необработанной строки, и приложение просто прикрепит его к HTTP-запросу?

РЕДАКТИРОВАТЬ: есть ли подобное элегантное решение, подобное @SamsonScharfrichter, описанному для HTTPfs? (Насколько мне известно, он не поддерживает токены делегирования)

EDIT2: Привет, ребята, я все еще полностью потерян. Я безуспешно пытаюсь разобраться с клиентом Hadoop-auth. Не могли бы вы помочь мне снова? Я уже часами безуспешно читал об этом. Примеры говорят сделать это:

* // establishing an initial connection
*
* URL url = new URL("http://foo:8080/bar");
* AuthenticatedURL.Token token = new AuthenticatedURL.Token();
* AuthenticatedURL aUrl = new AuthenticatedURL();
* HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection();
* ....
* // use the 'conn' instance
* ....

Я уже потерялся здесь. Какое начальное подключение мне нужно? Как может

new AuthenticatedURL(url, token).openConnection();

принять два параметра? для такого случая нет конструктора. (я получаю ошибку из-за этого). Разве не должен быть где-то указан принципал? Вероятно, это будет не так просто.

    URL url = new URL("http://<host>:14000/webhdfs/v1/?op=liststatus");
    AuthenticatedURL.Token token = new AuthenticatedURL.Token();

    HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection(url, token);

person MaBu    schedule 26.05.2016    source источник
comment
Я предполагаю, что это возможно сделать, однако это просто снова открывает дыру в безопасности, которую закрыл Kerberos. Я считаю, что Knox / Sentry позволяют вам получать доступ к данным через некоторые точки API, нет?   -  person OneCricketeer    schedule 26.05.2016
comment
Спасибо за подсказку, но я не могу использовать Knox, если он открывает дыру в безопасности, подлежит обсуждению, как только он заработает.   -  person MaBu    schedule 26.05.2016
comment
Насколько я знаю, все графические интерфейсы Hadoop и службы REST используют подписанный файл cookie для кэширования учетных данных Kerberos, кроме WebHDFS, который требует явного управления токеном делегирования. Возможно, можно создать файл cookie с одной библиотекой HTTP, а затем использовать его с другим сеансом - вам следует попытаться запустить соединение в режиме отладки с HttpFS, чтобы проверить, задействован ли файл cookie. И, надеюсь, ваш базовый HTTP-клиент не слишком прост и позволяет вам возиться с файлами cookie.   -  person Samson Scharfrichter    schedule 30.05.2016
comment
Большое спасибо, обновлю ветку, как только решение будет запущено.   -  person MaBu    schedule 31.05.2016
comment
Теперь я предлагаю вернуться к клиенту hadoop-auth. Проблема с зависимостью невелика (750 КБ), и предложенное мной решение связано с получением параметра авторизации и файла cookie, который соответствует HttpFS (HttpFS использует для аутентификации материал на стороне сервера hadoop-auth). Если вас беспокоит размер зависимостей, вы можете хотя бы взять исходный код из клиент hadoop-auth и используйте его.   -  person tellisnz    schedule 31.05.2016
comment
Вам также потребуется получить заголовок X-Hadoop-Delegation-Token, если он присутствует.   -  person tellisnz    schedule 31.05.2016
comment
Привет @MaBu, я обновил свой ответ, посмотрим, поможет ли это. Приносим извинения за предоставление неправильных параметров, оказалось, что документация неверна, и я отправил патч.   -  person tellisnz    schedule 10.06.2016


Ответы (2)


Использование Java-кода плюс Hadoop Java API для открытия сеанса Kerberized, получения токена делегирования для сеанса и передачи этого токена другому приложению, как это было предложено @tellisnz, имеет недостаток: Java API требует довольно много зависимостей (т. е. множество JAR-файлов, а также собственные библиотеки Hadoop). В частности, если вы запускаете свое приложение в Windows, это будет трудная поездка.

Другой вариант – использовать код Java и WebHDFS для выполнения одного запроса SPNEGO и ПОЛУЧИТЬ токен делегирования, а затем передать его другому приложению. Для этого варианта не требуется абсолютно никакой библиотеки Hadoop на вашем сервере. . Базовая версия будет похожа на sthg

URL urlGetToken = new URL("http://<host>:<port>/webhdfs/v1/?op=GETDELEGATIONTOKEN") ;
HttpURLConnection cnxGetToken =(HttpURLConnection) urlGetToken.openConnection() ;
BufferedReader httpMessage = new BufferedReader( new InputStreamReader(cnxGetToken.getInputStream()), 1024) ;
Pattern regexHasToken =Pattern.compile("urlString[\": ]+(.[^\" ]+)") ;
String httpMessageLine ;
while ( (httpMessageLine =httpMessage.readLine()) != null)
{ Matcher regexToken =regexHasToken.matcher(httpMessageLine) ;
  if (regexToken.find())
  { System.out.println("Use that template: http://<Host>:<Port>/webhdfs/v1%AbsPath%?delegation=" +regexToken.group(1) +"&op=...") ; }
}
httpMessage.close() ;

Это то, что я использую для доступа к HDFS из сценария Windows Powershell (или даже макроса Excel). Предостережение: в Windows вы должны создать свой Kerberos TGT на лету, передав JVM конфигурацию JAAS, указывающую на соответствующий файл keytab. Но это предостережение в любом случае относится и к Java API.

person Samson Scharfrichter    schedule 27.05.2016
comment
Спасибо большое! Попробую так и отпишусь, чем все закончилось. - person MaBu; 29.05.2016
comment
Нам удалось решить эту проблему, используя токен делегирования для WebHDFS и подписанный файл cookie для HTTPfs. Спасибо большое за вашу помощь. - person MaBu; 22.08.2016

Вы можете взглянуть на клиент hadoop-auth. и создайте службу, которая выполняет первое соединение, тогда вы сможете получить из нее заголовки «Авторизация» и «X-Hadoop-Delegation-Token» и файл cookie и добавить их к своим основным запросам клиента.

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

Затем, чтобы выполнить вход в WebHDFS/HttpFS, нам нужно сделать что-то вроде:

URL url = new URL("http://youhost:8080/your-kerberised-resource");
AuthenticatedURL.Token token = new AuthenticatedURL.Token();
HttpURLConnection conn = new AuthenticatedURL().openConnection(url, token);

String authorizationTokenString = conn.getRequestProperty("Authorization");
String delegationToken = conn.getRequestProperty("X-Hadoop-Delegation-Token");
...
// do what you have to to get your basic client connection
...
myBasicClientConnection.setRequestProperty("Authorization", authorizationTokenString);
myBasicClientConnection.setRequestProperty("Cookie", "hadoop.auth=" + token.toString());
myBasicClientConnection.setRequestProperty("X-Hadoop-Delegation-Token", delegationToken);
person tellisnz    schedule 26.05.2016
comment
Спасибо за совет, я имел в виду использование webhdfs-java-client. Я бы, вероятно, изменил его, чтобы вернуть билет службы после его получения. Мне было интересно, сработает ли это. - person MaBu; 26.05.2016
comment
Да, это выглядит немного старым. С помощью hadoop-auth это может быть так же просто, как редактирование выше. - person tellisnz; 27.05.2016