Giter VIP home page Giter VIP logo

django-shibboleth-remoteuser's Introduction

django-shibboleth-remoteuser

Build status

Middleware for using Shibboleth with Django. Requires Django 1.3 or above for RemoteAuthMiddleware.

Requirements

  • shibboleth-sp service installed on your system
  • shibboleth module enabled or compiled on your web server
  • Django >= 1.8 for version > 0.6 or Django > 1.3 for version <= 0.6

Installation and configuration

  1. Either checkout and run python setup.py install or install directly from GitHub using pip:

    pip install git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git
  2. In settings.py:
    • Enable the RemoteUserBackend.

      AUTHENTICATION_BACKENDS += (
          'shibboleth.backends.ShibbolethRemoteUserBackend',
      )
    • Add the Django Shibboleth middleware. You must add django.contrib.auth.middleware.ShibbolethRemoteUserMiddleware to the MIDDLEWARE_CLASSES setting after django.contrib.auth.middleware.AuthenticationMiddleware. For example:

      MIDDLEWARE_CLASSES = (
          ...
          'django.contrib.auth.middleware.AuthenticationMiddleware',
          'shibboleth.middleware.ShibbolethRemoteUserMiddleware',
          ...
      )
    • Map Shibboleth attributes to Django User models. The attributes must be stated in the form they have in the HTTP headers. Use this to populate the Django User object from Shibboleth attributes.

      The first element of the tuple states if the attribute is required or not. If a required element is not found in the parsed Shibboleth headers, an exception will be raised. For example, (True, "required_attribute"), (False, "optional_attribute).

      SHIBBOLETH_ATTRIBUTE_MAP = {
          "shib-user": (True, "username"),
          "shib-given-name": (True, "first_name"),
          "shib-sn": (True, "last_name"),
          "shib-mail": (False, "email"),
      }
    • Set the LOGIN_URL to the login handler of your Shibboleth installation. In most cases, this will be something like:

      LOGIN_URL = 'https://your_domain.edu/Shibboleth.sso/Login'
  3. Apache configuration - make sure the Shibboleth attributes are available to the app. The app url doesn't need to require Shibboleth.

    <Location /app>
      AuthType shibboleth
      Require shibboleth
    </Location>

Verify configuration

If you would like to verify that everything is configured correctly, follow the next two steps below. It will create a route in your application at /yourapp/shib/ that echos the attributes obtained from Shibboleth. If you see the attributes you mapped above on the screen, all is good.

  • Add shibboleth to installed apps.

    INSTALLED_APPS += (
        'shibboleth',
    )
  • Add below to urls.py to enable the included sample view. This view just echos back the parsed user attributes, which can be helpful for testing.

    urlpatterns += [
        url(r'^shib/', include('shibboleth.urls', namespace='shibboleth')),
    ]

At this point, the django-shibboleth-remoteuser middleware should be complete.

Optional

Template tags

Template tags are included which will allow you to place {{ login_link }} or {{ logout_link }} in your templates for routing users to the login or logout page. These are available as a convenience and are not required. To activate, add the following to settings.py:

TEMPLATES = [
    {
    ...
        'OPTIONS': {
            'context_processors': [
                ...
                'shibboleth.context_processors.login_link',
                'shibboleth.context_processors.logout_link',
                ...
            ],
        },
    ...
    },
]

Permission group mapping

It is possible to map a list of attributes to Django permission groups. django-shibboleth-remoteuser will generate the groups from the semicolon-separated values of these attributes. They will be available in the Django admin interface and you can assign your application permissions to them.

SHIBBOLETH_GROUP_ATTRIBUTES = ['Shibboleth-affiliation', 'Shibboleth-isMemberOf']

By default this value is empty and will not affect your group settings. But when you add attributes to SHIBBOLETH_GROUP_ATTRIBUTES the user will only associated with those groups. Be aware that the user will be removed from groups not defined in SHIBBOLETH_GROUP_ATTRIBUTES, if you enable this setting. Some installations may create a lot of groups. You may check your group attributes at https://your_domain.edu/Shibboleth.sso/Session before activating this feature.

Fields identified in SHIBBOLETH_GROUP_ATTRIBUTES can be a string of group names with a delimiter. By default the delimiter is ;, but this can be overridden to be one or many delimiters using the SHIBBOLETH_GROUP_DELIMITERS setting.

For example, given:
  • SHIBBOLETH_GROUP_ATTRIBUTES = ['Shibboleth-isMemberOf']
  • request headers includes: Shibboleth-isMemberOf: 'users;admins,managers'
SHIBBOLETH_GROUP_DELIMITERS Parsed Groups
default users and admins,managers
[','] users;admins and managers
[',', ';'] users, admins, and managers

django-shibboleth-remoteuser's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-shibboleth-remoteuser's Issues

default_shib_attributes and REMOTE_USER

Instead of:

default_shib_attributes = {
   "Shibboleth-eppn": (True, "username"),
}

how about:

default_shib_attributes = {
   "REMOTE_USER": (True, "username"),
}

The Apache mod_shib will of course set REMOTE_USER as that is the standard environment variable. In my case I did not see Shibboleth-eppn in my environment.

Trevor http://www.appazur.com

Documentation:

I had trouble getting things working, but I fixed it by using the Django base class, django.contrib.auth.backends.RemoteUserBackend, instead of ShibbolethRemoteUserBackend.

ShibbolethRemoteUserBackend will not match existing users based only on the username. Instead, ALL attributes must match (e.g. First Name, Last Name... whatever you've configured):

user = User.objects.get(**shib_user_params)

I would have expected that you could provide attributes for populating new user records, but that you would use a primary key field only (e.g. username) for matching with existing users. For example, what if the application changed a name field after the user was created (or in my case, the account was created without using Shibboleth).

Trevor http://www.appazur.com

Check for is_active

Django's RemoteUserBackend (as of 1.11) does not allow login from users with is_active=False This seems like a good thing to have in ShibbolethRemoteUserBackend too. Would you accept a PR for this?

Using django-shibboleth-remoteuser with LoginRequiredMixin from Django Braces

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.

error with Template tags

Hello

I tried to use the template tags
but i have this error :u'shibboleth' is not a registered namespace
in the settings.py file the modified parameter is TEMPLATE_CONTEXT_PROCESSORS

django 1.6

Thanks

In Django 1.6.5 get_fields doesn't exists

I got the following error by running your module to login.

'Options' object has no attribute 'get_fields'

Request Method: 	GET
Request URL: 	https://develop.klewel.com/watch/webcasts/
Django Version: 	1.6.5
Exception Type: 	AttributeError
Exception Value: 	

'Options' object has no attribute 'get_fields'

Exception Location: 	/usr/local/lib/python2.7/dist-packages/shibboleth/backends.py in authenticate, line 35
Python Executable: 	/usr/local/bin/uwsgi
Python Version: 	2.7.6
Python Path: 	

Apparently Django 1.6.5 doesn't support get_fileds() method but get_all_field_names() exists. Should I propose to you a pull request ?

Mock Shibboleth Headers

Hello,

I'm trying to create a local development environment to update our Shibboleth application. We want to be able to run it locally without the need for a real SAML IdP.

In the app settings file: https://github.com/Brown-University-Library/django-shibboleth-remoteuser/blob/master/shibboleth/app_settings.py#L11-L12 there's a SHIB_MOCK_HEADERS variable that is documented to do exactly what we want. The only issue is that it doesn't seem to do anything (and isn't referenced anywhere else through the code base).

Is there something I'm missing?

Thanks

No login possible after logout

During logout via the logout-view, the LOGOUT_SESSION_KEY is set, preventing the user from logging in.

As far as I can see, the user cannot log in again unless the login-view is used because only there the key is removed:

https://github.com/Brown-University-Library/django-shibboleth-remoteuser/blob/master/shibboleth/views.py#L55

I might be wrong though because this line does something I don't understand
https://github.com/Brown-University-Library/django-shibboleth-remoteuser/blob/master/shibboleth/middleware.py#L28

There are two possible ways to fix this:

The first one would be to make the login-view mandatory. This would also solve the other issue I have opened, but the settings would require a distinction between
LOGIN_URL and
SHIBBOLETH_LOGIN_URL

as it already exists for the logout process. This also solves my first issue.

The second fix would be to remove the whole LOGOUT_SESSION_KEY mechanism.
This also solves my my third issue.

I will suggest a fix within the next days if the issue is confirmed.

Unknown AssertionConsumerServiceURL Shibboleth.sso/SAML2/POST

I had configured everything, but getting an unknown url error after a successful login, while being redirected back to my protected page: 'Unknown AssertionConsumerServiceURL '

samlp:Status<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Requester"/>samlp:StatusMessageUnknown AssertionConsumerServiceURL https://mywebsite/Shibboleth.sso/SAML2/POST</samlp:StatusMessage></samlp:Status>

I found references to SAML2/POST in the C:\opt\shibboleth-sp\etc\shibboleth\protocols.xml, is this not supposed to be implemented by Shibboleth.sso intrinsically?

Not sure if I need to implement that or not... somehow. Any thoughts appreciated.

-thanks a lot!

Shibboleth headers not coming back when redirect URL is set

Hey all. We're running into a strange issue where shibboleth login works a charm when no redirect URL is given via the target querystring parameter, but when that target value is provided, we don't get any of the expected headers in the first request back from shibboleth (REMOTE_USER, SHIB_* variables, AUTH_TYPE: shibboleth, attributes we've requested via the SHIBBOLETH_ATTRIBUTE_MAP setting, etc.) and it results in an infinite redirect loop.

We use Django's login_required decorator to protect resources, and our LOGIN_URL setting is set to /Shibboleth.sso/Login. If we don't explicitly set the REDIRECT_FIELD_NAME to target, Django uses the default next, which shibboleth doesn't understand and is therefore ignored (#8 discusses this too). When we do set the REDIRECT_FIELD_NAME to target, the first request coming back from shibboleth is indeed at the correct redirect URL, but that request does not include any of the headers mentioned above. Don't know if it's relevant, but we do see a _shibsession_* cookie set.

Any ideas about what might be causing this? I can provide config settings if needed. Thanks in advance!

Stale request

When I add a "login_required" decoration to my view, Shibboleth tells me that my request is stale. Anyone ever dealt with this?

where is settings.py file ??

installed the setup.py and then I checked the shibboleth folder , whre is settings.py file? there is one file with name app_settings.

Licence

We would like to use django-shibboleth-remoteuser, but because it is not distributed under any licence, we can't. Is this by design or is it an oversight?

Problems with Django 2.1

I had to revert back to Django 2.0.8, otherwise, the login never succeeds (even though there is a valid session). I haven't found any error/warning in the logs. Seems to be silently failing and going back to the anonymous user. Reverting back to 2.0.8, reloading apache and refreshing the page reloads the authenticated page.

Shibboleth.sso/Login requires redirect url as ?target=url, not as ?next=url

I have set the LOGIN_URL to mydomain/Shibboleth.sso/Login

If I enter

mydomain/Shibboleth.sso/Login?target=redirectUrl 

I am being redirected corretly. Juding from my browser history, the automatic link created by this package is

mydomain/Shibboleth.sso/Login?next=redirectUrl

Strangely enough, I can't find the bug in the code, so it might as well have another cause.

See documentation here https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSessionCreationParameters

This might be different for older versions of shibboleth.

Permission groups from shibboleth attributes

Hello,
in my current Django application I have the problem that every user gets authenticated through our IdP. In my particular scenario the application must have special permission for our normal staff. Students should handled different. (I work for a university).

I came up with a solution to map existing shibboleth attributes to permission groups. To illustrate this see following example. I also used the attributes from the testcase at test_shib.py.

I would add following to my settings.py
SHIBBOLETH_GROUP_ATTRIBUTES = ['Shibboleth-affiliation', 'Shibboleth-isMemberOf']

When the user get logged in, it will be added to the Groups ['[email protected]', '[email protected]', 'SCHOOL:COMMUNITY:EMPLOYEE:ADMINISTRATIVE:BASE', 'SCHOOL:COMMUNITY:EMPLOYEE:STAFF:SAC:P', 'COMMUNITY:ALL', 'SCHOOL:COMMUNITY:EMPLOYEE:STAFF:SAC:M']

If the group does not exists, django-shibboleth-remoteuser will create the groups and add the user to this group. The user also will get removed from every other group not defined in the list above. Now you can add any permission from the application to this groups.
If SHIBBOLETH_GROUP_ATTRIBUTES = [] (which I would use for default) there will be no changes to the groups of the user, to ensure backward compatibility.

This is a similar approach like django-auth-ldap, where LDAP group attributes may map to Django permission groups (Which I like a lot.).

I definitely will implement this feature. I have the choice to do the generic approach (like described above) or implement my own ShibbolethRemoteUserBackend. If you would merge this approach (of course with documentation and tests) I would start next week. What do you think?

Incorrect encoding

Hi,

Some of our shibboleth attributes contain accentuated characters (sn). They are incorrectly encoded when the corresponding user is created in the database.

Frédéric => Frédéric

What could be wrong in our configuration ?

Thank you for your help.

Fred

Create a new release tag

It would be helpful to add a new release tag that includes the Django 2.0 compatibility commit.

Do not use ShibUseHeaders On . They pose an unnecessary security risk

The useage of
ShibUseHeaders On
poses a security risk and is not recommended:
https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAttributeAccess#NativeSPAttributeAccess-RequestHeaders

It is also not necessary since the shibboleth variables are populated via WSGI into the request.META dictionary. For example, without using ShibUseHeaders On, the META key of my application contains the following attributes:

persistent-id
unscoped-affiliation
orgunit-dn

and more.

PyPI?

This is a neat library - I use it in a couple of projects. It would be great to see it on PyPI and be able to pip install it.

0.12 release?

Hi,

0.11 is incompatible with Django 3.0+ due to the removal of django.utils.six, but the most recent fixes merged into master seem to address this. Any idea when we can expect an official 0.12 release available via PyPi? It's much easier to bundle into a requirements.txt file that way.

Thanks!

Logging Off Shibboleth

Thanks for a great module. Is there a default way to call the shibboleth logout page or do I need to write my own template tag, similar to the login tag included in the module?

Thanks

How is make_profile rewrite working ?

Hello, I try to create a profile in same time of user registration. I found a make_profile class in your middleware with the purpose to be rewritten in case of needs. So, I wrote something like this:

from shibboleth.middleware import ShibbolethRemoteUserMiddleware
from app.models.UserProfile import UserProfile

class ShibbolethRemoteUserMiddlewareWithProfile(ShibbolethRemoteUserMiddleware):
    def make_profile(self, user, shib_meta):
        UserProfile.objects.create(user=user)

And call this middleware object instead of the original one in my settings.py. But when new user is comming, the profile isn't created and if I put a logger, he will never be triggered.

Perhaps choose I the wrong approach to rewrite this method ?

Is the LOGOUT_SESSION_KEY a security issue?

The way I understood it is that this mechanism allows the user to be logged out of the application while still having an active shibboleth session.

In my eyes this is a security issue because it suggests to the user that he is logged out even though anyone with access to the computer can log back in by removing the LOGOUT_SESSION_KEY.

In my eyes, if a user is logged in to shibboleth he should be logged in to any application that bases on it. After all, Shibboleth is a software to support Single sign-on , and that's exactly what single sign on means.

A fix would be to remove this mechanism.

django-shibboleth-remoteuser won't install to virtual environment

Hi
I attempted to pip git+shibrepo install while my virtual environment for django project was activated and it still installs to the global python site-packages. Thus, a shibboleth module not found error occurs when running the app. (Testing the app with urls.py pointing to shibboleth.urls and the middleware class added)
Please advise

Remove user session instead of setting LOGOUT_SESSION_KEY on logout?

First: Thanks for this nice application!

May I ask: What are the reasons for checking the value of LOGOUT_SESSION_KEY in the session of the current user in the middleware?
The comment states, that this is needed for logout to work. But in my tests simply deleting the user session in the ShibbolethLogoutView seems to work as well and is cleaner in my opinion:

--- views.py.orig	2017-10-04 21:10:54.571524640 +0000
+++ views.py	2017-10-04 21:10:45.759517570 +0000
@@ -8,6 +8,7 @@
 from django.shortcuts import redirect
 from django.utils.decorators import method_decorator
 from django.views.generic import TemplateView
+from django.contrib.sessions.models import Session
 
 from urllib import quote
 
@@ -69,7 +70,8 @@
         auth.logout(self.request)
         #Set session key that middleware will use to force 
         #Shibboleth reauthentication.
-        self.request.session[LOGOUT_SESSION_KEY] = True
+        #self.request.session[LOGOUT_SESSION_KEY] = True
+        Session.objects.filter(session_key=self.request.session.session_key).delete()
         #Get target url in order of preference.
         target = LOGOUT_REDIRECT_URL or\
                  quote(request.build_absolute_uri())

Am I missing something?
Would you accept a pull request for the change (of course a complete PR, this is only a proof of concept)

python build dist support missing

We've been looking into installing django-shibboleth-remoteuser, but our sys-admin discovered it doesn't support python build dist. Is this something you all plan on adding or are you satisfied with things as they are. Note: our sys admins won't use pip so that may have been part of the issue. I had no issue installing via pip on my desktop.

Thanks,

Dean

install old version

what is the command to install an older version?
I have an error with this command: sudo pip install django-shibboleth-remoteuser-kennydude == 0.4

Could not find a version that satisfies the requirement django-shibboleth-remoteuser-kennydude == 0.4 (from versions: 0.5.macosx-10.11-intel, 0.6, 0.6.1, 0.6.2)

I connect to a server in ssh.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.