rzepinskip opened a new issue, #19519:
URL: https://github.com/apache/druid/issues/19519
### Affected Version
Druid 35.x (confirmed), likely all versions with `druid-kerberos` extension.
### Description
When using a mixed authenticator chain of `["ldap", "kerberos"]` (or any
chain where Kerberos is not the only authenticator), users accessing the web
console encounter an HTTP 403 error after their Kerberos authentication session
expires:
```
HTTP ERROR 403
org.apache.hadoop.security.authentication.util.SignerException: Invalid signed
text:
URI: /unified-console.html
STATUS: 403
MESSAGE: org.apache.hadoop.security.authentication.util.SignerException:
Invalid signed text:
```
Clearing all browser cookies for the Druid hostname resolves the issue
temporarily. Simply setting the `hadoop.auth` cookie to empty does not
reproduce the issue, because the browser will also attempt SPNEGO negotiation
in that case — the real problem is described below.
---
**Root cause — two interacting bugs:**
**Bug 1: Cookie "clear" does not instruct the browser to delete the cookie.**
When a Kerberos-authenticated session ends (token expiry, SPNEGO failure, or
any unauthenticated request), `doFilterSuper` in `KerberosAuthenticator` calls:
```java
tokenToAuthCookie(httpResponse, "", getCookieDomain(), getCookiePath(), 0,
false, isHttps);
```
The resulting `Set-Cookie` header is:
```
hadoop.auth=; Path=/; HttpOnly
```
No `Max-Age=0` or past `Expires` directive is included. Browsers treat this
as setting a session cookie with an empty value rather than deleting the
cookie. On subsequent requests, the browser keeps sending `hadoop.auth=` (empty
value).
**Bug 2: An empty cookie value short-circuits the entire authenticator chain
with a 403.**
In `KerberosAuthenticator.getToken()`, the cookie value is passed directly
to `Signer.verifyAndExtract()` without checking whether it is empty:
```java
tokenStr = cookie.getValue(); // ""
tokenStr = mySigner.verifyAndExtract(tokenStr); // throws SignerException:
"Invalid signed text:"
```
`Signer.verifyAndExtract("")` throws `SignerException` because the empty
string contains no `&s=` signature separator. This exception is caught and
stored as `authenticationEx`. Later in `doFilterSuper`:
```java
if (authenticationEx == null) {
filterChain.doFilter(request, response); // pass to next authenticator
(e.g. LDAP)
} else {
httpResponse.sendError(errCode, authenticationEx.getMessage()); // 403,
chain bypassed
}
```
Because `authenticationEx` is non-null, the filter immediately sends a 403
error and never passes the request to other authenticators in the chain. In a
`["ldap", "kerberos"]` setup, the LDAP authenticator never gets a chance to
handle the request, so the user cannot recover by entering their LDAP
credentials — they see a 403 with no login prompt.
---
**Reproduction steps:**
1. Configure Druid with an authenticator chain that includes both LDAP and
Kerberos (e.g. `druid.auth.authenticatorChain=["ldap","kerberos"]` with
`skipOnFailure=true` on both).
2. Log in to the Druid web console via SPNEGO/Kerberos. The browser receives
a signed `hadoop.auth` cookie (valid for ~10 hours by default).
3. Wait for the Kerberos authentication token to expire (default: 36000
seconds / 10 hours).
4. Attempt to access any Druid UI page (e.g. `/unified-console.html`).
5. Observe HTTP 403 with `SignerException: Invalid signed text:`.
6. Check browser cookies — `hadoop.auth` is present with an empty value.
**Workaround:** Manually delete (not clear) the `hadoop.auth` browser cookie
for the Druid hostname.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]