Răsfoiți Sursa

HUE-9037 [core] Add .cloudera.com to trusted host for CSRF token

When using https, Django will look at "HTTP_REFERER" request header to
see if it matches the current request's host when using unsafe (e.g.
POST) requests. When using Hue via Knox, the Knox host is the referrer
and if it is on a different host than the Hue host then it does not
match. To handle this, HUE-8750 adds the Knox host to
Django's CSRF_TRUSTED_ORIGINS and the Knox host is typically configured
via Cloudera Manager. Unfortunately, in Cloud scenario, the external
Knox host name may be different then the internal Knox host name and the
check fails yet again. To handle this, we're adding a new setting that
adds '.cloudera.com' as a trusted host.

Change-Id: Ida09bce0add7cc8a6ab89397fd3a9b580f7bee5b
Jean-Francois Desjeans Gauthier 6 ani în urmă
părinte
comite
cffe7381a1

+ 6 - 3
desktop/conf.dist/hue.ini

@@ -663,6 +663,9 @@
     # If set, limits the number of concurrent user sessions. 1 represents 1 browser session per user. Default: 0 (unlimited sessions per user)
     ## concurrent_user_session_limit=0
 
+    # A list of hosts which are trusted origins for unsafe requests. See django's CSRF_TRUSTED_ORIGINS for more information
+    ## trusted_origins=.cloudera.com
+
   # Configuration options for connecting to an external SMTP server
   # ------------------------------------------------------------------------
   [[smtp]]
@@ -685,9 +688,9 @@
   [[knox]]
 
     # This is a list of hosts that knox proxy requests can come from
-    ## knox_proxyhosts="server1.domain.com,server2.domain.com"
-    # Kerberos principal name which is allowed to impersonate others
-    ## knox_principal=knox
+    ## knox_proxyhosts=server1.domain.com,server2.domain.com
+    # List of Kerberos principal name which is allowed to impersonate others
+    ## knox_principal=knox1,knox2
 
   # Configuration options for Kerberos integration for secured Hadoop clusters
   # ------------------------------------------------------------------------

+ 5 - 2
desktop/conf/pseudo-distributed.ini.tmpl

@@ -665,6 +665,9 @@
     # If set, limits the number of concurrent user sessions. 1 represents 1 browser session per user. Default: 0 (unlimited sessions per user)
     ## concurrent_user_session_limit=0
 
+    # A list of hosts which are trusted origins for unsafe requests. See django's CSRF_TRUSTED_ORIGINS for more information
+    ## trusted_origins=.cloudera.com
+
   # Configuration options for connecting to an external SMTP server
   # ------------------------------------------------------------------------
   [[smtp]]
@@ -687,8 +690,8 @@
 
     # This is a list of hosts that knox proxy requests can come from
     ## knox_proxyhosts="server1.domain.com,server2.domain.com"
-    # Kerberos principal name which is allowed to impersonate others
-    ## knox_principal=knox
+    # List of Kerberos principal name which is allowed to impersonate others
+    ## knox_principal=knox1,knox2
 
 
   # Configuration options for Kerberos integration for secured Hadoop clusters

+ 9 - 3
desktop/core/src/desktop/conf.py

@@ -808,6 +808,12 @@ SESSION = ConfigSection(
       help=_("If set, limits the number of concurrent user sessions. 1 represents 1 session per user. Default: 0 (unlimited sessions per user)"),
       type=int,
       default=0,
+    ),
+    TRUSTED_ORIGINS = Config(
+      key="trusted_origins",
+      help=_("A list of hosts which are trusted origins for unsafe requests. See django's CSRF_TRUSTED_ORIGINS for more information"),
+      type=coerce_csv,
+      default='.cloudera.com',
     )
   )
 )
@@ -818,13 +824,13 @@ KNOX = ConfigSection(
   members=dict(
     KNOX_PRINCIPAL=Config(
       key='knox_principal',
-      help=_("Kerberos principal name for Hue. Typically 'knox/hostname.foo.com'."),
-      type=str,
+      help=_("Comma separated list of Kerberos principal name for Hue. Typically 'knox/hostname.foo.com'."),
+      type=coerce_csv,
       default="knox/%s" % socket.getfqdn()),
     KNOX_PROXYHOSTS = Config(
       key='knox_proxyhosts',
       default="%s" % socket.getfqdn(),
-      type=str,
+      type=coerce_csv,
       help=_('Comma separated list of strings representing the host names that the Hue server can trust as knox hosts.')
     ),
   )

+ 3 - 2
desktop/core/src/desktop/middleware.py

@@ -672,7 +672,7 @@ class SpnegoMiddleware(object):
           if 'desktop.auth.backend.KnoxSpnegoDjangoBackend' in \
                 desktop.conf.AUTH.BACKEND.get():
             knox_verification = False
-            if desktop.conf.KNOX.KNOX_PRINCIPAL.get() in username:
+            if username in desktop.conf.KNOX.KNOX_PRINCIPAL.get():
               # This may contain chain of reverse proxies, e.g. knox proxy, hue load balancer
               # Compare hostname on both HTTP_X_FORWARDED_HOST & KNOX_PROXYHOSTS. Both of these can be configured to use either hostname or IPs and we have to normalize to one or the other
               req_hosts = self.clean_host(request.META['HTTP_X_FORWARDED_HOST'])
@@ -720,7 +720,8 @@ class SpnegoMiddleware(object):
   def clean_host(self, pattern):
     hosts = []
     if pattern:
-      for hostport in pattern.split(','):
+      pattern_list = pattern if isinstance(pattern, list) else pattern.split(',')
+      for hostport in pattern_list:
         host = hostport.split(':')[0].strip()
         try:
           hosts.append(socket.gethostbyaddr(host)[0])

+ 10 - 1
desktop/core/src/desktop/settings.py

@@ -417,9 +417,18 @@ SESSION_COOKIE_HTTPONLY = desktop.conf.SESSION.HTTP_ONLY.get()
 CSRF_COOKIE_SECURE = desktop.conf.SESSION.SECURE.get()
 CSRF_COOKIE_HTTPONLY = desktop.conf.SESSION.HTTP_ONLY.get()
 CSRF_COOKIE_NAME='csrftoken'
+
+TRUSTED_ORIGINS = []
+if desktop.conf.SESSION.TRUSTED_ORIGINS.get():
+  TRUSTED_ORIGINS += desktop.conf.SESSION.TRUSTED_ORIGINS.get()
+
 # This is required for knox
 if desktop.conf.KNOX.KNOX_PROXYHOSTS.get(): # The hosts provided here don't have port. Add default knox port
-  CSRF_TRUSTED_ORIGINS=[host.split(':')[0] + ':' + (host.split(':')[1] if len(host.split(':')) > 1 else '8443') for host in desktop.conf.KNOX.KNOX_PROXYHOSTS.get().split(',')]
+  TRUSTED_ORIGINS += desktop.conf.KNOX.KNOX_PROXYHOSTS.get()
+  TRUSTED_ORIGINS = [host.split(':')[0] + ':' + (host.split(':')[1] if len(host.split(':')) > 1 else '8443') for host in TRUSTED_ORIGINS]
+
+if TRUSTED_ORIGINS:
+  CSRF_TRUSTED_ORIGINS = TRUSTED_ORIGINS
 
 SECURE_HSTS_SECONDS = desktop.conf.SECURE_HSTS_SECONDS.get()
 SECURE_HSTS_INCLUDE_SUBDOMAINS = desktop.conf.SECURE_HSTS_INCLUDE_SUBDOMAINS.get()