[jb] Fix mutual authentication failed with Isilon
@@ -83,6 +83,7 @@ def _negotiate_value(response):
class HTTPKerberosAuth(AuthBase):
"""Attaches HTTP GSSAPI/Kerberos Authentication to the given Request
object."""
+
def __init__(self, mutual_authentication=REQUIRED, service="HTTP"):
self.context = {}
self.mutual_authentication = mutual_authentication
@@ -103,6 +104,7 @@ class HTTPKerberosAuth(AuthBase):
urlparse(response.url).port,
threading.current_thread().ident)
+ log.debug("generate_request_header(): host_port_thread: {0}".format(host_port_thread))
try:
result, self.context[host_port_thread] = kerberos.authGSSClientInit(
"{0}@{1}".format(self.service, host))
@@ -232,11 +234,24 @@ class HTTPKerberosAuth(AuthBase):
urlparse(response.url).port,
threading.current_thread().ident)
+ log.debug("authenticate_server(): host_port_thread: {0}".format(host_port_thread))
try:
result = kerberos.authGSSClientStep(self.context[host_port_thread],
_negotiate_value(response))
- except kerberos.GSSError:
- log.exception("authenticate_server(): authGSSClientStep() failed:")
+ except kerberos.GSSError as e:
+ # Since Isilon's webhdfs host and port will be the same for
+ # both 'NameNode' and 'DataNode' connections, Mutual Authentication will fail here
+ # due to the fact that a 307 redirect is made to the same host and port.
+ # host_port_thread will be the same when calling authGssClientStep().
+ # If we get a "Context is already fully established" response, that is OK if
+ # the response.url contains "datanode=true". "datanode=true" is Isilon-specific
+ # in that it is not part of CDH. It is an indicator to the Isilon server
+ # that the operation is a DataNode operation.
+
+ if 'datanode=true' in response.url and 'Context is already fully established' in e.args[1][0]:
+ log.debug("Caught Isilon mutual auth exception %s - %s" % (response.url, e.args[1][0]))
+ return True
+ log.exception("GSSError: authenticate_server(): authGSSClientStep() failed:")
return False
if result < 1:
