Эх сурвалжийг харах

[auth] Fix SpnegoMiddleware upgrade issue (#1954)

Ying Chen 4 жил өмнө
parent
commit
1320fe1cb7

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

@@ -633,7 +633,7 @@ class ProxyMiddleware(object):
     return username
     return username
 
 
 
 
-class SpnegoMiddleware(object):
+class SpnegoMiddleware(MiddlewareMixin):
   """
   """
   Based on the WSGI SPNEGO middlware class posted here:
   Based on the WSGI SPNEGO middlware class posted here:
   http://code.activestate.com/recipes/576992/
   http://code.activestate.com/recipes/576992/
@@ -647,7 +647,7 @@ class SpnegoMiddleware(object):
       LOG.info('Unloading SpnegoMiddleware')
       LOG.info('Unloading SpnegoMiddleware')
       raise exceptions.MiddlewareNotUsed
       raise exceptions.MiddlewareNotUsed
 
 
-  def __call__(self, request):
+  def process_request(self, request):
     """
     """
     The process_request() method needs to communicate some state to the
     The process_request() method needs to communicate some state to the
     process_response() method. The two options for this are to return an
     process_response() method. The two options for this are to return an
@@ -754,8 +754,7 @@ class SpnegoMiddleware(object):
         request.META['Return-401'] = ''
         request.META['Return-401'] = ''
       return
       return
 
 
-    response = self.get_response(request)
-
+  def process_response(self, request, response):
     if 'GSS-String' in request.META:
     if 'GSS-String' in request.META:
       response['WWW-Authenticate'] = request.META['GSS-String']
       response['WWW-Authenticate'] = request.META['GSS-String']
     elif 'Return-401' in request.META:
     elif 'Return-401' in request.META:
@@ -763,7 +762,6 @@ class SpnegoMiddleware(object):
         status=401)
         status=401)
       response['WWW-Authenticate'] = 'Negotiate'
       response['WWW-Authenticate'] = 'Negotiate'
       response.status = 401
       response.status = 401
-
     return response
     return response
 
 
   def clean_host(self, pattern):
   def clean_host(self, pattern):

+ 45 - 0
desktop/core/src/desktop/middleware_test.py

@@ -17,9 +17,11 @@
 
 
 import json
 import json
 import os
 import os
+import sys
 import tempfile
 import tempfile
 
 
 from django.conf import settings
 from django.conf import settings
+from django.test.client import Client
 from nose.tools import assert_equal, assert_false, assert_true
 from nose.tools import assert_equal, assert_false, assert_true
 from nose.plugins.skip import SkipTest
 from nose.plugins.skip import SkipTest
 
 
@@ -29,6 +31,10 @@ from desktop.conf import AUDIT_EVENT_LOG_DIR
 from desktop.lib.django_test_util import make_logged_in_client
 from desktop.lib.django_test_util import make_logged_in_client
 from desktop.lib.test_utils import add_permission
 from desktop.lib.test_utils import add_permission
 
 
+if sys.version_info[0] > 2:
+  from unittest.mock import patch, Mock
+else:
+  from mock import patch, Mock
 
 
 def test_view_perms():
 def test_view_perms():
   # Super user
   # Super user
@@ -156,3 +162,42 @@ def test_ensure_safe_redirect_middleware():
     settings.MIDDLEWARE.pop()
     settings.MIDDLEWARE.pop()
     for finish in done:
     for finish in done:
       finish()
       finish()
+
+def test_spnego_middleware():
+  done = []
+  orig_backends = settings.AUTHENTICATION_BACKENDS
+  try:
+    # use SpnegoDjangoBackend to enable 'desktop.middleware.SpnegoMiddleware'
+    done.append(desktop.conf.AUTH.BACKEND.set_for_testing(['desktop.auth.backend.SpnegoDjangoBackend']))
+    settings.AUTHENTICATION_BACKENDS = (['desktop.auth.backend.SpnegoDjangoBackend'])
+
+    c = Client()
+    with patch('kerberos.authGSSServerInit') as authGSSServerInit, \
+         patch('kerberos.authGSSServerStep') as authGSSServerStep, \
+         patch('kerberos.authGSSServerResponse') as authGSSServerResponse, \
+         patch('kerberos.authGSSServerClean') as authGSSServerClean, \
+         patch('kerberos.authGSSServerUserName') as authGSSServerUserName:
+      authGSSServerInit.return_value = 1, 'context'
+      authGSSServerStep.return_value = 1
+      authGSSServerResponse.return_value = 'gssstring'
+      authGSSServerClean.return_value = None
+      authGSSServerUserName.return_value = 'spnego_test'
+
+      header = {'HTTP_AUTHORIZATION': 'Negotiate test'}
+      response = c.get("/hue/editor/?type=impala", **header)
+      assert_equal(200, response.status_code)
+      assert_equal(response['WWW-Authenticate'], 'Negotiate %s' % authGSSServerResponse.return_value)
+
+    c = Client()
+    response = c.get("/hue/editor/?type=impala")
+    assert_equal(401, response.status_code)
+
+    c = Client()
+    response = c.get("/desktop/debug/is_alive")
+    assert_equal(200, response.status_code)
+  finally:
+    settings.MIDDLEWARE.pop()
+    for finish in done:
+      finish()
+    settings.AUTHENTICATION_BACKENDS = orig_backends
+