Browse Source

HUE-9415 [impala] Support connecting to Impala's webui with basic auth (#1214)

Impala added the ability to secure the webui with basic http
username/password authentication to LDAP in IMPALA-9537. This patch
adds a flag to configure Hue to authenticate to Impala's webui with
basic auth.

Co-authored-by: Romain Rigaux <romain.rigaux@gmail.com>
Thomas Tauber-Marshall 5 years ago
parent
commit
61a92137ae

+ 7 - 0
apps/impala/src/impala/conf.py

@@ -229,6 +229,13 @@ DAEMON_API_USERNAME = Config(
   dynamic_default=get_daemon_api_username
 )
 
+DAEMON_API_AUTH_SCHEME = Config(
+  key="daemon_api_auth_scheme",
+  help=_t("The authentication scheme to use with 'daemon_api_username' and 'daemon_api_password' when authenticating to the Impala Daemon UI, either 'digest' (default) or 'basic'."),
+  private=False,
+  default="digest"
+)
+
 def get_use_sasl_default():
   """kerberos enabled or password is specified"""
   return is_kerberos_enabled() or AUTH_PASSWORD.get() is not None # Maps closely to legacy behavior

+ 7 - 4
apps/impala/src/impala/server.py

@@ -28,7 +28,7 @@ from beeswax.server.hive_server2_lib import HiveServerClient
 
 from ImpalaService import ImpalaHiveServer2Service
 from impala.impala_flags import get_webserver_certificate_file, is_webserver_spnego_enabled, is_kerberos_enabled
-from impala.conf import DAEMON_API_USERNAME, DAEMON_API_PASSWORD, COORDINATOR_URL
+from impala.conf import DAEMON_API_USERNAME, DAEMON_API_PASSWORD, DAEMON_API_AUTH_SCHEME, COORDINATOR_URL
 
 
 LOG = logging.getLogger(__name__)
@@ -143,9 +143,12 @@ class ImpalaDaemonApi(object):
 
     # You can set username/password for Impala Web UI which overrides kerberos
     if DAEMON_API_USERNAME.get() is not None and DAEMON_API_PASSWORD.get() is not None:
-      self._client.set_digest_auth(DAEMON_API_USERNAME.get(), DAEMON_API_PASSWORD.get())
-      LOG.info('Using username and password for authentication')
-
+      if DAEMON_API_AUTH_SCHEME.get().lower() == 'basic':
+        self._client.set_basic_auth(DAEMON_API_USERNAME.get(), DAEMON_API_PASSWORD.get())
+        LOG.info("Using username and password for basic authentication")
+      else:
+        self._client.set_digest_auth(DAEMON_API_USERNAME.get(), DAEMON_API_PASSWORD.get())
+        LOG.info('Using username and password for digest authentication')
     elif self._webserver_spnego_enabled or self._security_enabled:
       self._client.set_kerberos_auth()
       LOG.info('Using kerberos principal for authentication')

+ 41 - 1
apps/impala/src/impala/server_tests.py

@@ -53,6 +53,7 @@ class TestImpalaDaemonApi():
 
           server._client.set_digest_auth.assert_called()
           server._client.set_kerberos_auth.assert_not_called()
+          server._client.set_basic_auth.assert_not_called()
 
     with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
       with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
@@ -64,6 +65,39 @@ class TestImpalaDaemonApi():
 
           server._client.set_digest_auth.assert_not_called()
           server._client.set_kerberos_auth.assert_not_called()
+          server._client.set_basic_auth.assert_not_called()
+
+
+  def test_basic_auth(self):
+
+    with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
+      with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
+        with patch('impala.server.HttpClient') as HttpClient:
+          with patch('impala.server.DAEMON_API_AUTH_SCHEME.get') as DAEMON_API_AUTH_SCHEME_get:
+            DAEMON_API_USERNAME_get.return_value = 'impala'
+            DAEMON_API_PASSWORD_get.return_value = 'impala'
+            DAEMON_API_AUTH_SCHEME_get.return_value = 'basic'
+
+            server = ImpalaDaemonApi('localhost')
+
+            server._client.set_basic_auth.assert_called()
+            server._client.set_digest_auth.assert_not_called()
+            server._client.set_kerberos_auth.assert_not_called()
+
+    with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
+      with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
+        with patch('impala.server.HttpClient') as HttpClient:
+          with patch('impala.server.DAEMON_API_AUTH_SCHEME.get') as DAEMON_API_AUTH_SCHEME_get:
+            DAEMON_API_USERNAME_get.return_value = 'impala'
+            DAEMON_API_PASSWORD_get.return_value = None
+            DAEMON_API_AUTH_SCHEME_get.return_value = 'basic'
+
+            server = ImpalaDaemonApi('localhost')
+
+            server._client.set_basic_auth.assert_not_called()
+            server._client.set_digest_auth.assert_not_called()
+            server._client.set_kerberos_auth.assert_not_called()
+
 
   def test_kerberos_auth(self):
 
@@ -80,6 +114,7 @@ class TestImpalaDaemonApi():
 
             server._client.set_digest_auth.assert_called()
             server._client.set_kerberos_auth.assert_not_called()
+            server._client.set_basic_auth.assert_not_called()
 
     with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
       with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
@@ -95,6 +130,7 @@ class TestImpalaDaemonApi():
 
             server._client.set_digest_auth.assert_not_called()
             server._client.set_kerberos_auth.assert_not_called()
+            server._client.set_basic_auth.assert_not_called()
 
     with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
       with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
@@ -108,6 +144,7 @@ class TestImpalaDaemonApi():
 
             server._client.set_digest_auth.assert_not_called()
             server._client.set_kerberos_auth.assert_called()
+            server._client.set_basic_auth.assert_not_called()
 
     with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
       with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
@@ -122,6 +159,7 @@ class TestImpalaDaemonApi():
 
             server._client.set_digest_auth.assert_not_called()
             server._client.set_kerberos_auth.assert_called()
+            server._client.set_basic_auth.assert_not_called()
 
     with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
       with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
@@ -137,6 +175,7 @@ class TestImpalaDaemonApi():
 
               server._client.set_digest_auth.assert_not_called()
               server._client.set_kerberos_auth.assert_not_called()
+              server._client.set_basic_auth.assert_not_called()
 
     with patch('impala.server.DAEMON_API_USERNAME.get') as DAEMON_API_USERNAME_get:
       with patch('impala.server.DAEMON_API_PASSWORD.get') as DAEMON_API_PASSWORD_get:
@@ -151,4 +190,5 @@ class TestImpalaDaemonApi():
               server = ImpalaDaemonApi('localhost')
 
               server._client.set_digest_auth.assert_not_called()
-              server._client.set_kerberos_auth.assert_called()
+              server._client.set_kerberos_auth.assert_called()
+              server._client.set_basic_auth.assert_not_called()

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

@@ -1363,11 +1363,13 @@
   ## auth_password=
 
   # Username and password for Impala Daemon Web interface for getting Impala queries in JobBrowser
-  # Set when webserver_htpassword_user and webserver_htpassword_password are set for Impala
   ## daemon_api_username=
   ## daemon_api_password=
   # Execute this script to produce the password to avoid entering in clear text
   ## daemon_api_password_script=
+  # Set to 'digest' when webserver_htpassword_user and webserver_htpassword_password are set for Impala, or set to
+  # 'basic' if webserver_require_ldap is set
+  ## daemon_api_auth_scheme=
 
   # A comma-separated list of white-listed Impala configuration properties that users are authorized to set.
   # config_whitelist=debug_action,explain_level,mem_limit,optimize_partition_key_scans,query_timeout_s,request_pool

+ 3 - 1
desktop/conf/pseudo-distributed.ini.tmpl

@@ -1348,11 +1348,13 @@
   ## auth_password=
 
   # Username and password for Impala Daemon Web interface for getting Impala queries in JobBrowser
-  # Set when webserver_htpassword_user and webserver_htpassword_password are set for Impala
   ## daemon_api_username=
   ## daemon_api_password=
   # Execute this script to produce the password to avoid entering in clear text
   ## daemon_api_password_script=
+  # Set to 'digest' when webserver_htpassword_user and webserver_htpassword_password are set for Impala, or set to
+  # 'basic' if webserver_require_ldap is set
+  ## daemon_api_auth_scheme=
 
   # A comma-separated list of white-listed Impala configuration properties that users are authorized to set.
   ## config_whitelist=debug_action,explain_level,mem_limit,optimize_partition_key_scans,query_timeout_s,request_pool