I have the following scenario:
- I have an HTTP service where I have a logged in user with a keytab and a kerberos principal - let's name this user for the sake of the example
service_user
- Then I have a client which invokes this service and authenticates itself via kerberos (spnego) - let's name the user who invokes the service
client_user
- From my service I would like to launch a Yarn Java application (which works perfectly) and at the end from the Yarn container I need to invoke my service's callback endpoint which requires authentication
- Inside the Yarn container I'm not in a kerberized environment, I only have delegation tokens
- So ideally my service should accept spnego and delegation token authentications as well
I had a look at DelegationTokenAuthenticationFilter
, but I wasn't able to figure out how I should be using it. I added it to my service and I see that DelegationTokenAuthenticationHandler#managementOperation
can handle requests where I have op=GETDELEGATIONTOKEN
in the query part. If I do something like curl --negotiate -u : http://host:port/callback?op= GETDELEGATIONTOKEN
from command line I get back a delegation token which is fine.
But that's not what I want, right? What I would like to do is: client_user
invoking my service, authenticating itself via spnego, the service creating a custom delegation token for client_user
, passing that delegation token to the Yarn container (I set the HADOOP_TOKEN_FILE_LOCATION
env variable), and then from the Yarn container calling back to my service using the delegation token I created.
I also tried creating a delegation token on my own way:
DelegationTokenManager tokenManager = new DelegationTokenManager(conf, new Text("..."));
tokenManager.init();
Token<? extends AbstractDelegationTokenIdentifier> token = tokenManager.createToken(ugi, renewer);
Credentials credentials = ...
credentials.addToken(new Text("..."), token);
Then this was available in my Yarn container where I did:
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());
And I see the DelegationTokenAuthenticationFilter
picking up my token, but it's saying it's invalid. Something about it not being signed.
Am I even on the right path at all? Should I maybe forget about DelegationTokenAuthenticationFilter
and simply extend AuthenticationFilter
where I can accept a custom delegation token header in the HTTP request? Or should I use DelegationTokenAuthenticationFilter
and try to override DelegationTokenManager#verifyToken
somehow?
I see that for creating an HttpURLConnection in the Yarn container I could use DelegationTokenAuthenticatedURL.openConnection
, but that requires a kerberized environment.