1

I am using Django 1.9, Python 3, running locally on Docker (for testing)
Trying to integrate django-saml2-auth into my application.
Pretty much followed all the steps in the docs:
1) All installations were successful
2) New URLs were imported above the rest
3) Installed apps includes 'django_saml2_auth'
4) 'SAML2_AUTH' dict was placed in settings (and all attributes were mapped)
5) In the SAML2 identity provider (using OneLogin), the Single-sign-on URL and Audience URI(SP Entity ID) was set to http://127.0.0.1:8000/saml2_auth/acs/

What happens is that when I get to http://127.0.0.1:8000/admin the browser goes into an infinite redirect loop:

...
[02/May/2018 15:43:06] "GET /admin/ HTTP/1.1" 302 0
[02/May/2018 15:43:06] "GET /admin/login/?next=/admin/ HTTP/1.1" 302 0
[02/May/2018 15:43:07] "POST /saml2_auth/acs/ HTTP/1.1" 302 0
[02/May/2018 15:43:07] "GET /admin/ HTTP/1.1" 302 0
[02/May/2018 15:43:07] "GET /admin/login/?next=/admin/ HTTP/1.1" 302 0
[02/May/2018 15:43:08] "POST /saml2_auth/acs/ HTTP/1.1" 302 0
[02/May/2018 15:43:08] "GET /admin/ HTTP/1.1" 302 0
...
  • When I disable django-saml2-auth I see that a staff user was created.
  • In the OneLogin interface I can see that I logged in successfully.

  • Overriding django_saml2_auth.views.signin(r), where r is a django.core.handlers.wsgi.WSGIRequest, for <WSGIRequest: GET '/admin/login/?next=/admin/'>, and in the request, the user is set to AnonymousUser, COOKIES contain sessionid and csrftoken.

I would expect that a session would start for the user that was created/fetched, and that I will get to an /admin/<whatever> page.

I will appreciate any help in debugging this, thank you!

EDIT: I was able to get it to work by removing AUTHENTICATION_BACKENDS from settings.py- I have 3 other backends that I use. It seems like they conflict with django-saml2-auth.
Is there any way to get django-saml2-auth to work with other backends?

EDIT 2: Will try to integrate django-saml2-pro-auth, which has a backend so will not conflict. I would really appreciate some insight though.

EDIT 3: back to EDIT 2, when I remove all the backends and they don't conflict, the log flow looks like that:

[04/May/2018 15:24:26] "GET /admin/ HTTP/1.1" 302 0
[04/May/2018 15:24:27] "GET /admin/login/?next=/admin/ HTTP/1.1" 302
[04/May/2018 15:26:27] "POST /saml2_auth/acs/ HTTP/1.1" 302 0
[04/May/2018 15:26:27] "GET /admin/ HTTP/1.1" 200 38398

Where the last GET does not get redirected, with 200.

camelBack
  • 748
  • 2
  • 11
  • 30

1 Answers1

0

Issue resolved: After taking a deeper dive- it seems like this code is the issue:
In django_saml2_auth/views.py, acs():

if target_user.is_active:
  target_user.backend = 'django.contrib.auth.backends.ModelBackend'
  login(r, target_user)
else:
  return HttpResponseRedirect(get_reverse([denied, 'denied', 'django_saml2_auth:denied']))

It seems like the default ModelBackend is necessary. When other backends are used, the default is no longer used by Django, and hence the infinite loop. If the default backend is added to the list of backends, everything works as intended.

camelBack
  • 748
  • 2
  • 11
  • 30