Как реализовать пользовательский токен делегирования

#hadoop #token #hadoop-yarn #kerberos-delegation

#hadoop #токен #hadoop-yarn #kerberos-делегирование

Вопрос:

У меня следующий сценарий:

  • У меня есть HTTP-служба, в которой у меня есть зарегистрированный пользователь с keytab и принципалом kerberos — давайте назовем этого пользователя для примера service_user
  • Затем у меня есть клиент, который вызывает эту службу и аутентифицирует себя через kerberos (spnego) — давайте назовем пользователя, который вызывает службу client_user
  • Из моей службы я хотел бы запустить Java-приложение Yarn (которое работает отлично), и в конце из контейнера Yarn мне нужно вызвать конечную точку обратного вызова моей службы, которая требует аутентификации
  • Внутри контейнера Yarn я не в кербер-среде, у меня есть только токены делегирования
  • Поэтому в идеале мой сервис должен также принимать проверки подлинности spnego и токенов делегирования

Я посмотрел DelegationTokenAuthenticationFilter , но я не смог понять, как я должен его использовать. Я добавил его в свой сервис и вижу, что DelegationTokenAuthenticationHandler#managementOperation он может обрабатывать запросы, которые у меня есть op=GETDELEGATIONTOKEN в части запроса. Если я делаю что-то вроде curl --negotiate -u : http://host:port/callback?op= GETDELEGATIONTOKEN из командной строки, я получаю обратно токен делегирования, и это нормально.

Но это не то, чего я хочу, верно? Что я хотел бы сделать, так это: client_user вызвать мою службу, аутентифицироваться с помощью spnego, служба создает пользовательский токен делегирования client_user , передает этот токен делегирования в контейнер Yarn (я устанавливаю переменную HADOOP_TOKEN_FILE_LOCATION env), а затем из контейнера Yarn перезванивает в мою службу, используя созданный мной токен делегирования.

Я также попытался создать токен делегирования по-своему:

 DelegationTokenManager tokenManager = new DelegationTokenManager(conf, new Text("..."));
tokenManager.init();
Token<? extends AbstractDelegationTokenIdentifier> token = tokenManager.createToken(ugi, renewer);
Credentials credentials = ...
credentials.addToken(new Text("..."), token);
  

Затем это было доступно в моем контейнере Yarn, где я сделал:

 import static org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticator.DELEGATION_TOKEN_HEADER;

UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
Credentials credentials = currentUser.getCredentials();
Token<? extends TokenIdentifier> delegationToken = credentials.getToken(new Text("..."));
HttpURLConnection connection = ...
connection.setRequestProperty(DELEGATION_TOKEN_HEADER, delegationToken.encodeToUrlString());
  

И я вижу DelegationTokenAuthenticationFilter , что он собирает мой токен, но он говорит, что он недействителен. Что-то о том, что он не подписан.

Я вообще на правильном пути? Может быть, мне следует забыть об DelegationTokenAuthenticationFilter этом и просто расширить AuthenticationFilter , где я могу принять заголовок пользовательского токена делегирования в HTTP-запросе? Или я должен использовать DelegationTokenAuthenticationFilter и попытаться DelegationTokenManager#verifyToken как-то переопределить?

Я вижу, что для создания HttpURLConnection в контейнере Yarn я мог бы использовать DelegationTokenAuthenticatedURL.openConnection , но для этого требуется кербер-среда.

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

1. SPNego поддерживает Kerberos и / или NTLM. Больше ничего. Вам необходимо отправить keytab внутри каждого «клиентского» контейнера и динамически создать Kerberos TGT из кода Java, прежде чем вызывать «сервер», и позволить HTTP-клиенту автоматически обрабатывать запрос / ответ.

2. Токены делегирования Hadoop — это просто пользовательский трюк, упрощающий работу с Kerberos (предназначенный для аутентификации «точка-точка») внутри распределенной системы. Короче говоря, токен основан на взаимном доверии между узлами Hadoop. и службы Hadoop. У внешних служб нет причин подтверждать это пользовательское доверительное отношение.