Skip to content

Commit 8d5eb82

Browse files
[django] fixes for django-saml infinite redirect error
There were two issues 1. saml urls needed to be made accessible without auth 2. and without csrf.
1 parent 2a373cb commit 8d5eb82

File tree

4 files changed

+30
-59
lines changed

4 files changed

+30
-59
lines changed

desktop/core/src/desktop/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,11 @@
581581
if SAML_AUTHENTICATION:
582582
from libsaml.saml_settings import * # noqa: F403
583583
INSTALLED_APPS.append('libsaml')
584+
INSTALLED_APPS.append('djangosaml2')
584585
LOGIN_URL = '/saml2/login/'
585586
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
587+
# Add required middleware for djangosaml2 1.9.3+
588+
MIDDLEWARE.append('djangosaml2.middleware.SamlSessionMiddleware')
586589

587590
# Middleware classes.
588591
for middleware in desktop.conf.MIDDLEWARE.get():

desktop/libs/libsaml/src/libsaml/backend.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from desktop.conf import AUTH
3333
from desktop.lib.django_util import nonce_attribute
3434
from libsaml import conf, metrics
35-
from useradmin.models import User, UserProfile, get_default_user_group, get_profile
35+
from useradmin.models import get_default_user_group, get_profile, User, UserProfile
3636

3737
LOG = logging.getLogger()
3838

@@ -56,7 +56,7 @@ def clean_user_main_attribute(self, main_attribute):
5656
"""
5757
return force_username_case(main_attribute)
5858

59-
def is_authorized(self, attributes, attribute_mapping):
59+
def is_authorized(self, attributes, attribute_mapping, user=None, session_info=None):
6060
"""Hook to allow custom authorization policies based on user belonging to a list of SAML groups."""
6161
LOG.debug('is_authorized() attributes = %s' % attributes)
6262
LOG.debug('is_authorized() attribute_mapping = %s' % attribute_mapping)
@@ -133,6 +133,6 @@ def _get_user_by_username(self, username):
133133
user = User.objects.get(username__iexact=username)
134134
else:
135135
user = User.objects.get(username=username)
136-
except User.DoesNotExist as e:
136+
except User.DoesNotExist:
137137
user = None
138138
return user

desktop/libs/libsaml/src/libsaml/urls.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,32 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717

18-
import sys
1918
import logging
2019

2120
from django.urls import re_path
2221

2322
LOG = logging.getLogger()
2423

2524
try:
26-
from djangosaml2 import views as djangosaml2_views
25+
from libsaml.views import AssertionConsumerServiceView, EchoAttributesView, LoginView, LogoutView, MetadataView
2726

28-
from libsaml import views as libsaml_views
29-
except ImportError:
30-
LOG.warning('djangosaml2 module not found')
31-
djangosaml2_views = None
32-
33-
try:
34-
from djangosaml2.views import logout_service_post
35-
except ImportError:
36-
# We are on an older version of djangosaml2
37-
logout_service_post = None
38-
39-
40-
if djangosaml2_views is not None:
4127
urlpatterns = [
42-
re_path(r'^logout/$', djangosaml2_views.LogoutView.as_view(), name='saml2_logout')
28+
re_path(r'^logout/$', LogoutView.as_view(), name='saml2_logout'),
29+
re_path(r'^ls/$', LogoutView.as_view(), name='saml2_ls'),
30+
re_path(r'^acs/$', AssertionConsumerServiceView.as_view(), name='saml2_acs'),
31+
re_path(r'^login/$', LoginView.as_view(), name='saml2_login'),
32+
re_path(r'^metadata/$', MetadataView.as_view(), name='saml2_metadata'),
33+
re_path(r'^test/$', EchoAttributesView.as_view())
4334
]
4435

45-
urlpatterns += [
46-
re_path(r'^ls/$', libsaml_views.LogoutView.as_view(), name='saml2_ls'),
47-
re_path(r'^acs/$', libsaml_views.CustomAssertionConsumerServiceView.as_view(), name='saml2_acs'),
48-
re_path(r'^login/$', libsaml_views.LoginView.as_view(), name='saml2_login'),
49-
re_path(r'^metadata/$', libsaml_views.MetadataView.as_view(), name='saml2_metadata'),
50-
re_path(r'^test/$', libsaml_views.EchoAttributesView.as_view())
51-
]
36+
try:
37+
from libsaml.views import LogoutServicePostView
5238

53-
if logout_service_post is not None:
5439
urlpatterns += [
55-
re_path(r'^ls/post/$', libsaml_views.LogoutServicePostView.as_view(), name='saml2_ls_post')
40+
re_path(r'^ls/post/$', LogoutServicePostView.as_view(), name='saml2_ls_post')
5641
]
42+
except ImportError:
43+
# We are on an older version of djangosaml2
44+
pass
45+
except ImportError:
46+
LOG.warning('djangosaml2 module not found')

desktop/libs/libsaml/src/libsaml/views.py

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,18 @@
1414
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
17-
from django.views.decorators.csrf import csrf_exempt
18-
from django.views.decorators.http import require_POST
1917
from djangosaml2.views import AssertionConsumerServiceView, EchoAttributesView, LoginView, LogoutView, MetadataView
2018

19+
LoginView.dispatch.login_notrequired = True
20+
EchoAttributesView.dispatch.login_notrequired = True
21+
MetadataView.dispatch.login_notrequired = True
22+
LogoutView.dispatch.login_notrequired = True
23+
AssertionConsumerServiceView.dispatch.login_notrequired = True
24+
2125
try:
2226
from djangosaml2.views import LogoutServicePostView
27+
28+
LogoutServicePostView.dispatch.login_notrequired = True
2329
except ImportError:
2430
# We are on an older version of djangosaml2
25-
LogoutServicePostView = None
26-
27-
import libsaml.conf
28-
29-
30-
# Customize AssertionConsumerServiceView
31-
class CustomAssertionConsumerServiceView(AssertionConsumerServiceView):
32-
def dispatch(self, request, *args, **kwargs):
33-
username_source = libsaml.conf.USERNAME_SOURCE.get().lower()
34-
return super().dispatch(request, *args, **kwargs)
35-
36-
# Expose the views
37-
38-
39-
login = LoginView
40-
echo_attributes = EchoAttributesView
41-
metadata = MetadataView
42-
assertion_consumer_service = CustomAssertionConsumerServiceView
43-
logout_service = LogoutView
44-
logout_service_post = LogoutServicePostView
45-
46-
__all__ = ['login', 'echo_attributes', 'assertion_consumer_service', 'metadata', 'logout_service', 'logout_service_post']
47-
48-
# Set login_notrequired attribute
49-
for view in [LogoutView, LoginView, EchoAttributesView, AssertionConsumerServiceView, MetadataView]:
50-
setattr(view, 'login_notrequired', True)
51-
52-
if LogoutServicePostView is not None:
53-
setattr(LogoutServicePostView, 'login_notrequired', True)
31+
pass

0 commit comments

Comments
 (0)