Bläddra i källkod

[core] Implement Hue SAML LOGOUT URL for CDP. Redirect the client to logout URL when idle session timeout has expired

Prakash Ranade 4 år sedan
förälder
incheckning
de7503b762

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

@@ -63,6 +63,8 @@ from desktop.lib.view_util import is_ajax
 from desktop.log import get_audit_logger
 from desktop.log.access import access_log, log_page_hit, access_warn
 
+from libsaml.conf import CDP_LOGOUT_URL
+
 if sys.version_info[0] > 2:
   from django.utils.translation import gettext as _
   from django.utils.http import url_has_allowed_host_and_scheme
@@ -384,11 +386,12 @@ class LoginAndPermissionMiddleware(MiddlewareMixin):
 
     logging.info("Redirecting to login page: %s", request.get_full_path())
     access_log(request, 'login redirection', level=access_log_level)
-    no_idle_backends = (
-        "libsaml.backend.SAML2Backend",
+    no_idle_backends = [
         "desktop.auth.backend.SpnegoDjangoBackend",
         "desktop.auth.backend.KnoxSpnegoDjangoBackend"
-    )
+    ]
+    if CDP_LOGOUT_URL.get() == "":
+      no_idle_backends.append("libsaml.backend.SAML2Backend")
     if request.ajax and all(no_idle_backend not in AUTH.BACKEND.get() for no_idle_backend in no_idle_backends):
       # Send back a magic header which causes Hue.Request to interpose itself
       # in the ajax request and make the user login before resubmitting the

+ 10 - 0
desktop/core/src/desktop/templates/common_header_footer_components.mako

@@ -409,6 +409,16 @@ else:
     var isLoginRequired = false;
     $(document).ajaxComplete(function (event, xhr, settings) {
       if (xhr.responseText === '/* login required */') {
+        if (window.SAML_LOGOUT_URL) {
+          var logoutForm = $('<form action="' + window.SAML_LOGOUT_URL + '" method="POST"></form>');
+
+          if (window.SAML_REDIRECT_URL) {
+            var logoutRedirect = $('<input name="logoutRedirect" type="hidden" value="' + window.SAML_REDIRECT_URL + '" />');
+            logoutRedirect.appendTo(logoutForm);
+          }
+          logoutForm.appendTo('body').submit();
+        }
+
         var isAutoLogout = settings.url == '/desktop/debug/is_idle';
         $('.blurred').removeClass('blurred');
 

+ 4 - 0
desktop/core/src/desktop/templates/global_js_constants.mako

@@ -29,6 +29,7 @@
   from jobbrowser.conf import ENABLE_HISTORY_V2
   from filebrowser.conf import SHOW_UPLOAD_BUTTON, REMOTE_STORAGE_HOME
   from indexer.conf import ENABLE_NEW_INDEXER
+  from libsaml.conf import get_logout_redirect_url, CDP_LOGOUT_URL
   from metadata.conf import has_catalog, has_readonly_catalog, has_optimizer, has_workload_analytics, OPTIMIZER, get_optimizer_url, \
       get_catalog_url, get_optimizer_mode
   from metastore.conf import ENABLE_NEW_CREATE_TABLE
@@ -82,6 +83,9 @@
   window.KNOX_BASE_PATH = window._KNOX_BASE_PATH.indexOf('KNOX_BASE_PATH_KNOX') < 0 ? window._KNOX_BASE_PATH_KNOX : '';
   window.KNOX_BASE_URL = window._KNOX_BASE_URL.indexOf('KNOX_BASE_URL') < 0 ? window._KNOX_BASE_URL : '';
 
+  window.SAML_LOGOUT_URL = '${ CDP_LOGOUT_URL.get() }';
+  window.SAML_REDIRECT_URL = '${ get_logout_redirect_url() }';
+
   window.HAS_GIT = ${ len(VCS.keys()) } > 0;
   window.HAS_MULTI_CLUSTER = '${ get_cluster_config(user)['has_computes'] }' === 'True';
 

+ 7 - 0
desktop/libs/libsaml/src/libsaml/backend.py

@@ -120,6 +120,13 @@ class SAML2Backend(_Saml2Backend):
       response = saml_logout(request)
       auth_logout(request)
       return response
+    elif conf.CDP_LOGOUT_URL.get():
+      auth_logout(request)
+      redirect_url = conf.get_logout_redirect_url()
+      html = '<html><body onload="document.forms[0].submit()">' \
+             '<form action="%s" method="POST"><input name="logoutRedirect" type="hidden" value="%s"/></form>' \
+             '</body></html>' % (conf.CDP_LOGOUT_URL.get(), redirect_url)
+      return HttpResponse(html)
     else:
       return None
 

+ 13 - 0
desktop/libs/libsaml/src/libsaml/conf.py

@@ -206,6 +206,11 @@ REQUIRED_GROUPS_ATTRIBUTE = Config(
   type=str,
   help=_t("Name of the SAML attribute containing the list of groups the user belongs to."))
 
+CDP_LOGOUT_URL = Config(
+  key="logout_url",
+  type=str,
+  default="",
+  help=_t("To log users out of magic-sso, CDP control panel use Logout URL"))
 
 def get_key_file_password():
   password = os.environ.get('HUE_SAML_KEY_FILE_PASSWORD')
@@ -224,3 +229,11 @@ def config_validator(user):
   if USERNAME_SOURCE.get() not in USERNAME_SOURCES:
     res.append(("libsaml.username_source", _("username_source not configured properly. SAML integration may not work.")))
   return res
+
+def get_logout_redirect_url():
+  # This logic was derived from KNOX.
+  prod_url = "console.altus.cloudera.com"
+  redirect_url = "https://sso.cloudera.com/bin/services/support/api/public/logout"
+  if prod_url not in CDP_LOGOUT_URL.get():
+    redirect_url = "https://sso.staging-upgrade.aem.cloudera.com/bin/services/support/api/public/logout"
+  return redirect_url