Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using django-shibboleth-remoteuser with LoginRequiredMixin from Django Braces #41

Open
FlipperPA opened this Issue May 26, 2016 · 5 comments

Comments

Projects
None yet
3 participants
@FlipperPA
Copy link
Contributor

FlipperPA commented May 26, 2016

I'm attempting to use django-shibboleth-remoteuser with the permission mixins from Django braces. However, it seems that the session is being lost after the first click. We had a similar issue with CoSign authentication using remote user, which was solved by using the new PersistentRemoteUserMiddleware:

https://docs.djangoproject.com/en/1.9/ref/middleware/#django.contrib.auth.middleware.PersistentRemoteUserMiddleware

We are trying to use the LoginRequiredMixin to protect the site to keep it controlled by Django (so that we could fall back on Django's auth, for example, if Shib isn't available for any reason), and only protect the LOGIN_URL ('/Shibboleth.sso/Login') with Shibboleth's gatekeeper.

I'm not sure the problem is the same, as this is my first time using Shibboleth. We have shibboleth with Apache successfully redirecting to our IdP for login, and when it returns, it creates the user and we've dumped {{ request.username }} successfully into a template. However, on ensuing clicks, it is no longer populated. I'm wondering if anyone has run into this problem. I'm including various settings and code snippets below.

Apache config:

LoadModule wsgi_module modules/mod_wsgi.so

WSGISocketPrefix /var/run/wsgi

Listen 443
<VirtualHost *:443>
  ServerName vagrant.ourserver.com
  ErrorLog /home/vagrant/apache_errors.log

  SSLENGINE on

  SSLCertificateFile /etc/pki/tls/certs/localhost.crt
  SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
  SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
  SSLProtocol all -SSLv2

  WSGIDaemonProcess shibdemo-https python-home=/home/vagrant/.virtualenvs/shibdemo
  WSGIProcessGroup shibdemo-https
  WSGIScriptAlias / /vagrant/html/shibdemo/shibdemo/wsgi.py process-group=shibdemo-https application-group=shibdemo-https
  <Directory /vagrant/html/shibdemo/shibdemo>
    Require all granted
  </Directory>
  Alias /static/ /vagrant/html/shibdemo/static/
  <Directory /vagrant/html/shibdemo/static>
    Require all granted
  </Directory>


  <Location /pennkey>
    AuthType shibboleth
    Require valid-user
    ShibRequireSession on
  </Location>

  <Location /Shibboleth.sso>
    SetHandler shib
  </Location>
</VirtualHost>

Relevant Django settings:

SHIBBOLETH_ATTRIBUTE_MAP = {
    "eppn": (True, "username"),
    "givenName": (True, "first_name"),
    "sn": (True, "last_name"),
    "mail": (False, "email"),
}

MIDDLEWARE_CLASSES = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'shibboleth.middleware.ShibbolethRemoteUserMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'shibboleth',
    'pennkey',
    'about',
)

AUTHENTICATION_BACKENDS = [
    'shibboleth.backends.ShibbolethRemoteUserBackend',
    'django.contrib.auth.backends.ModelBackend',
]

LOGIN_URL = '/Shibboleth.sso/Login'

urlpatterns:

urlpatterns = [
    url(r'^$', TemplateView.as_view(template_name='shibdemo/home.html'), name='home'),
    url(r'^other/$', login_required(TemplateView.as_view(template_name='shibdemo/other.html'), login_url='/admin/'), name='home'),
    url(r'^about/$', AboutView.as_view(), name='about'),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^pennkey/', include('pennkey.urls', namespace='pennkey')),
    url(r'^shib/', include('shibboleth.urls', namespace='shibboleth')),
]

Example views for the 'about' Django app:

from django.views.generic import TemplateView
from braces.views import LoginRequiredMixin


class AboutView(LoginRequiredMixin, TemplateView):
    template_name = 'about/about.html'

Our Shibboleth XML files would seem to be okay since we can hit https://vagrant.ourserver.com/Shibboleth.sso/Login and successfully auth with our IdP, and see the returned user created. We're on CentOS 7.2 with Apache 2.4. Apologies if this isn't the right place to ask, and let me know if I should include more details. Thanks in advance.

@bcail

This comment has been minimized.

Copy link
Contributor

bcail commented May 26, 2016

Normally what we do with this package is to have the whole site protected by Shib, even if a valid session isn't required for every page. So, for example, we would have something like this:

<Location /pennkey>
    AuthType shibboleth
    Require valid-user
    ShibRequireSession on
  </Location>

  <Location /Shibboleth.sso>
    SetHandler shib
  </Location>

<Location />
    AuthType shibboleth
    ShibRequireSession off
    Require Shibboleth
  </Location>

Does that fix the issue for you? If it does, would you still need a different solution, or are you OK with that?

@FlipperPA

This comment has been minimized.

Copy link
Contributor Author

FlipperPA commented Jun 9, 2016

Just FYI, I haven't forgotten this. This got us part of the way there, but we're working on a solution which may help others. We're working on protecting a single Django URL route with Shib, then allowing Django's login_required() to handle the rest. We're also including an example where anything with login_required() is protected by Shib, but a single URL route/view uses Django's auth instead.

I'll post it here when we get it, and issue a PR for the README, in case it might help. Thanks for all your efforts!

@bcail

This comment has been minimized.

Copy link
Contributor

bcail commented Jun 10, 2016

Great!

@bcail

This comment has been minimized.

Copy link
Contributor

bcail commented Jul 12, 2016

Please try the latest code with PR #43, and see if that helps this issue.

@jrhoads

This comment has been minimized.

Copy link
Member

jrhoads commented May 15, 2017

@FlipperPA and @bcail is this still an active issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.