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:
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:
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:
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:
- Configure Druid with an authenticator chain that includes both LDAP and Kerberos (e.g.
druid.auth.authenticatorChain=["ldap","kerberos"] with skipOnFailure=true on both).
- Log in to the Druid web console via SPNEGO/Kerberos. The browser receives a signed
hadoop.auth cookie (valid for ~10 hours by default).
- Wait for the Kerberos authentication token to expire (default: 36000 seconds / 10 hours).
- Attempt to access any Druid UI page (e.g.
/unified-console.html).
- Observe HTTP 403 with
SignerException: Invalid signed text:.
- 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.
Affected Version
Druid 35.x (confirmed), likely all versions with
druid-kerberosextension.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:Clearing all browser cookies for the Druid hostname resolves the issue temporarily. Simply setting the
hadoop.authcookie 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),
doFilterSuperinKerberosAuthenticatorcalls:The resulting
Set-Cookieheader is:No
Max-Age=0or pastExpiresdirective 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 sendinghadoop.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 toSigner.verifyAndExtract()without checking whether it is empty:Signer.verifyAndExtract("")throwsSignerExceptionbecause the empty string contains no&s=signature separator. This exception is caught and stored asauthenticationEx. Later indoFilterSuper:Because
authenticationExis 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:
druid.auth.authenticatorChain=["ldap","kerberos"]withskipOnFailure=trueon both).hadoop.authcookie (valid for ~10 hours by default)./unified-console.html).SignerException: Invalid signed text:.hadoop.authis present with an empty value.Workaround: Manually delete (not clear) the
hadoop.authbrowser cookie for the Druid hostname.