Selaa lähdekoodia

Hue sends X-Forwarded-For header in thrift calls made via HTTP-transport-mode to Hive (#3176)

Co-authored-by: Athithyaa Selvam <aselvam@cloudera.com>
Athithyaa Selvam 2 vuotta sitten
vanhempi
commit
d543df0bf9

+ 26 - 0
apps/beeswax/gen-py/TCLIService/TCLIService.py

@@ -15,7 +15,10 @@ import logging
 from .ttypes import *
 from thrift.Thrift import TProcessor
 from thrift.transport import TTransport
+from django.utils.functional import wraps
+from django.utils.encoding import smart_str
 all_structs = []
+LOG = logging.getLogger(__name__)
 
 
 class Iface(object):
@@ -212,6 +215,28 @@ class Iface(object):
         pass
 
 
+def add_xff_header(func):
+  def decorate(*args, **kwargs):
+    self = args[0]
+    xff = None
+    configuration = None
+    if args[1].__dict__ is not None and 'configuration' in args[1].__dict__:
+      configuration = args[1].__dict__['configuration']
+    if configuration is not None and 'HTTP-X-FORWARDED-FOR' in configuration:
+        xff = configuration.get('HTTP-X-FORWARDED-FOR')
+    try:
+        if hasattr(self._oprot.trans, 'TFramedTransport'):
+          trans_client = self._oprot.trans._TFramedTransport__trans
+        else:
+          trans_client = self._oprot.trans._TBufferedTransport__trans
+
+        trans_client.setCustomHeaders({'HTTP-X-FORWARDED-FOR': xff})
+    except AttributeError as e:
+        LOG.error('Could not set HTTP-X-FORWARDED-FOR header: %s' % smart_str(e))
+
+    return func(*args, **kwargs)
+  return wraps(func)(decorate)
+
 class Client(Iface):
     def __init__(self, iprot, oprot=None):
         self._iprot = self._oprot = iprot
@@ -219,6 +244,7 @@ class Client(Iface):
             self._oprot = oprot
         self._seqid = 0
 
+    @add_xff_header
     def OpenSession(self, req):
         """
         Parameters:

+ 6 - 0
apps/beeswax/src/beeswax/server/hive_server2_lib.py

@@ -677,6 +677,9 @@ class HiveServerClient(object):
 
     if self.query_server['server_name'] == 'beeswax': # All the time
       kwargs['configuration'].update({'hive.server2.proxy.user': user.username})
+      xff_header = json.loads(user.userprofile.json_data).get('HTTP-X-FORWARDED-FOR', None)
+      if xff_header:
+        kwargs['configuration'].update({'HTTP-X-FORWARDED-FOR': xff_header})
 
     if self.query_server['server_name'] == 'hplsql' or interpreter['dialect'] == 'hplsql': # All the time
       kwargs['configuration'].update({'hive.server2.proxy.user': user.username, 'set:hivevar:mode': 'HPLSQL'})
@@ -689,6 +692,9 @@ class HiveServerClient(object):
 
     if self.query_server.get('dialect') == 'impala' and self.query_server['SESSION_TIMEOUT_S'] > 0:
       kwargs['configuration'].update({'idle_session_timeout': str(self.query_server['SESSION_TIMEOUT_S'])})
+      xff_header = json.loads(user.userprofile.json_data).get('HTTP-X-FORWARDED-FOR', None)
+      if xff_header:
+        kwargs['configuration'].update({'HTTP-X-FORWARDED-FOR': xff_header})
 
     LOG.info('Opening %s thrift session for user %s' % (self.query_server['server_name'], user.username))
 

+ 6 - 1
desktop/core/src/desktop/auth/views.py

@@ -51,6 +51,7 @@ from desktop.lib.exceptions_renderable import PopupException
 from desktop.log.access import access_log, access_warn, last_access_map
 from desktop.views import samlgroup_check
 from desktop.settings import LOAD_BALANCER_COOKIE
+from django.utils.encoding import smart_str
 
 
 if sys.version_info[0] > 2:
@@ -163,6 +164,10 @@ def dt_login(request, from_modal=False):
         if userprofile.creation_method == UserProfile.CreationMethod.EXTERNAL: # This is to fix a bug in Hue 4.3
           userprofile.creation_method = UserProfile.CreationMethod.EXTERNAL.name
         userprofile.update_data({'auth_backend': user.backend})
+        try:
+          userprofile.update_data({'HTTP-X-FORWARDED-FOR': request.META['HTTP_X_FORWARDED_FOR']})
+        except KeyError as e:
+          LOG.error('HTTP-X-FORWARDED-FOR header not found: %s' %smart_str(e))
         userprofile.save()
 
         msg = 'Successful login for user: %s' % user.username
@@ -201,7 +206,7 @@ def dt_login(request, from_modal=False):
     # local user login failed, give the right auth_form with 'server' field
     auth_form = auth_forms.LdapAuthenticationForm()
   
-  if not from_modal and SESSION.ENABLE_TEST_COOKIE.get() :
+  if not from_modal and SESSION.ENABLE_TEST_COOKIE.get():
     request.session.set_test_cookie()
 
   if 'SAML2Backend' in backend_names:

+ 1 - 0
desktop/core/src/desktop/management/commands/rungunicornserver.py

@@ -151,6 +151,7 @@ def argprocessing(args=[], options={}):
 def rungunicornserver(args=[], options={}):
   gunicorn_options = {
       'accesslog': "-",
+      'access_log_format': "%({x-forwarded-for}i)s %(h)s %(l)s %(u)s %(t)s '%(r)s' %(s)s %(b)s '%(f)s' '%(a)s'",
       'backlog': 2048,
       'bind': [options['bind_addr']],
       'ca_certs': conf.SSL_CACERTS.get(),     # CA certificates file

+ 4 - 0
desktop/core/src/desktop/middleware.py

@@ -948,4 +948,8 @@ class MultipleProxyMiddleware:
         if ',' in request.META[field]:
           parts = request.META[field].split(',')
           request.META[field] = parts[-1].strip()
+
+    if 'HTTP_X_FORWARDED_FOR' not in request.META and 'REMOTE_ADDR' in request.META:
+      request.META['HTTP_X_FORWARDED_FOR'] = request.META['REMOTE_ADDR']
+
     return self.get_response(request)

+ 1 - 1
tools/container/huelb/hue_httpd_template

@@ -12,7 +12,7 @@ ErrorLog "${HUE_LOG_DIR}/httpd_error_log"
 LogLevel warn
 
 <IfModule log_config_module>
-  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+  LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
   LogFormat "%h %l %u %t \"%r\" %>s %b" common
   CustomLog "${HUE_LOG_DIR}/httpd_access_log" common
 </IfModule>