Browse Source

HUE-8321 [oidc] Add implementation for multi-backend auth with AllowFirstUserDjangoBackend

Ying Chen 7 years ago
parent
commit
408ea6eb48

+ 9 - 3
desktop/core/src/desktop/auth/backend.py

@@ -47,6 +47,7 @@ from django_auth_ldap.config import LDAPSearch
 
 import desktop.conf
 from desktop import metrics
+from desktop.settings import LOAD_BALANCER_COOKIE
 from liboauth.metrics import oauth_authentication_time
 from mozilla_django_oidc.auth import OIDCAuthenticationBackend, default_username_algo
 from mozilla_django_oidc.utils import absolutify, import_from_settings
@@ -699,9 +700,12 @@ class OIDCBackend(OIDCAuthenticationBackend):
 
   def logout(self, request, next_page):
     # https://stackoverflow.com/questions/46689034/logout-user-via-keycloak-rest-api-doesnt-work
+    if request.session.get('_auth_user_backend', '') != 'desktop.auth.backend.OIDCBackend':
+      return None
+
     session = request.session
-    access_token = session['oidc_access_token']
-    refresh_token = session['oidc_refresh_token']
+    access_token = session.get('oidc_access_token', '')
+    refresh_token = session.get('oidc_refresh_token', '')
 
     if access_token and refresh_token:
       oidc_logout_url = desktop.conf.OIDC.LOGOUT_REDIRECT_URL.get()
@@ -722,7 +726,9 @@ class OIDCBackend(OIDCAuthenticationBackend):
         LOG.debug("OpenID Connect logout succeed!")
         delete_oidc_session_tokens(session)
         auth.logout(request)
-        return HttpResponseRedirect(next_page)
+        response = HttpResponseRedirect(next_page)
+        response.delete_cookie(LOAD_BALANCER_COOKIE)
+        return response
       else:
         LOG.error("OpenID Connect logout failed: %s" % resp.content)
     else:

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

@@ -159,7 +159,7 @@ def dt_login(request, from_modal=False):
     first_user_form = None
     auth_form = AuthenticationForm()
     # SAML user is already authenticated in djangosaml2.views.login
-    if 'SAML2Backend' in backend_names and request.user.is_authenticated():
+    if ('OIDCBackend' in backend_names or 'SAML2Backend' in backend_names) and request.user.is_authenticated():
       try:
         ensure_home_directory(request.fs, request.user)
       except (IOError, WebHdfsException), e:

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

@@ -262,6 +262,12 @@ class AppSpecificMiddleware(object):
 
 
 class LoginAndPermissionMiddleware(object):
+  def process_request(self, request):
+    # When local user login, oidc middleware refresh token if oidc_id_token_expiration doesn't exists!
+    if request.session.get('_auth_user_backend', '') == 'desktop.auth.backend.AllowFirstUserDjangoBackend'\
+            and 'desktop.auth.backend.OIDCBackend' in desktop.conf.AUTH.BACKEND.get():
+      request.session['oidc_id_token_expiration'] = time.time() + 300
+
   """
   Middleware that forces all views (except those that opt out) through authentication.
   """

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

@@ -463,7 +463,9 @@ def is_oidc_configured():
 
 if is_oidc_configured():
   INSTALLED_APPS.append('mozilla_django_oidc')
-  LOGIN_URL = '/oidc/authenticate/'
+  if 'desktop.auth.backend.AllowFirstUserDjangoBackend' not in AUTHENTICATION_BACKENDS:
+    # when multi-backend auth, standard login URL '/hue/accounts/login' is used.
+    LOGIN_URL = '/oidc/authenticate/'
   SESSION_EXPIRE_AT_BROWSER_CLOSE = True
   MIDDLEWARE_CLASSES.append('mozilla_django_oidc.middleware.SessionRefresh')
   OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS = 15 * 60

File diff suppressed because it is too large
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/login.css


+ 6 - 0
desktop/core/src/desktop/templates/login.mako

@@ -81,6 +81,12 @@ ${ commonheader(_("Welcome to Hue"), "login", user, request, "50px", True, True)
     </div>
     <h3>Query. Explore. Repeat.</h3>
 
+    %if 'OIDCBackend' in backend_names:
+      <button title="${ _('Single Sign-on') }" class="btn btn-primary" onclick="location.href='/oidc/authenticate/'">${ _('Single Sign-on') }</button>
+
+      <hr class="separator-line"/>
+    %endif
+
     %if first_login_ever:
       <div class="alert alert-info center">
         ${_('Since this is your first time logging in, pick any username and password. Be sure to remember these, as')}

Some files were not shown because too many files changed in this diff