#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. У внешних служб нет причин подтверждать это пользовательское доверительное отношение.