-
Notifications
You must be signed in to change notification settings - Fork 58
Description
When a Client is instanciated with a custom_auth header that contains a Kerberos Authorization: Negotiate <base64 authenticator> header, that header is used in every client.request method call. However, by definition, these authenticator tokens can be used only once.
This is problematic, because client.execute calls client.request multiple times, to first submit the query and then poll for the result, with the same headers.
Here's an example to demonstrate the issue, with curl, and with the nodejs kerberos library to get the kerberos header.
> const kerberos = await import("kerberos");
undefined
> krb = await kerberos.Kerberos.initializeClient("presto@presto.example.com", {mechOID: kerberos.GSS_MECH_OID_KRB5, principal: "HTTP/app.example.com@REALM"});
KerberosClient {}
> await krb.step("")
'YIIDT...wmRFK9Q=='$ curl -s \
--service presto \
-H "Authorization: Negotiate YIIDT...wmRFK9Q==" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-Presto-User: brouberol' \
-d '{"query": "SELECT 1"}' \
https://presto.example.org:8281/v1/statement
...
{
"id": "20251121_091834_00661_5x3zf",
"infoUri": "https://presto.example.org:8281/ui/query.html?20251121_091834_00661_5x3zf",
"nextUri": "https://presto.example.org:8281/v1/statement/queued/20251121_091834_00661_5x3zf/1?slug=xe92f5bb4728e4654a3d3577411f1aab3",
"stats": {
"state": "WAITING_FOR_PREREQUISITES",
"waitingForPrerequisites": true,
"queued": false,
"scheduled": false,
"nodes": 0,
"totalSplits": 0,
"queuedSplits": 0,
"runningSplits": 0,
"completedSplits": 0,
"cpuTimeMillis": 0,
"wallTimeMillis": 0,
"waitingForPrerequisitesTimeMillis": 0,
"queuedTimeMillis": 0,
"elapsedTimeMillis": 0,
"processedRows": 0,
"processedBytes": 0,
"peakMemoryBytes": 0,
"peakTotalMemoryBytes": 0,
"peakTaskTotalMemoryBytes": 0,
"spilledBytes": 0
},
"warnings": []
}However, any subsequent call using the same token returns an HTTP 401:
$ curl -s \
--service presto \
-H "Authorization: Negotiate YIIDT...wmRFK9Q==" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-Presto-User: brouberol'
-X GET \
https://presto.example.org:8281/v1/statement/queued/20251121_091834_00661_5x3zf/1?slug=xe92f5bb4728e4654a3d3577411f1aab3 -v
...
* upload completely sent off: 21 out of 21 bytes
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Authentication failed for token: TOK==
< Date: Fri, 21 Nov 2025 09:20:29 GMT
< WWW-Authenticate: Negotiate
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Length: 0
<
* Connection #0 to host an-coord1003.eqiad.wmnet left intactThis is why curl has a --negotiate flag, that uses libgssapi to negotiate a new authenticator for each request. The issue here is that presto-client-node assumes that the user must provide the client with a kerberos header, and does not provide them with a pre-request hook that could be used to renew the authorization header.
Another strategy could be to rely on a kerberos-aware http library that would perform the negotiation for the user.
In the current state though, Kerberos support does not work AFAICT.
Thanks and happy to hear your thoughts!