| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- Metadata-Version: 1.1
- Name: djangosaml2
- Version: 0.13.0
- Summary: pysaml2 integration in Django
- Home-page: https://bitbucket.org/lgs/djangosaml2
- Author: Yaco Sistemas
- Author-email: lgs@yaco.es
- License: Apache 2.0
- Description: .. contents::
-
- ===========
- djangosaml2
- ===========
-
- djangosaml2 is a Django application that integrates the PySAML2 library
- into your project. This mean that you can protect your Django based project
- with a service provider based on PySAML. This way it will talk SAML2 with
- your Identity Provider allowing you to use this authentication mechanism.
- This document will guide you through a few simple steps to accomplish
- such goal.
-
-
- Installation
- ============
-
- PySAML2 uses xmlsec1_ binary to sign SAML assertions so you need to install
- it either through your operating system package or by compiling the source
- code. It doesn't matter where the final executable is installed because
- you will need to set the full path to it in the configuration stage.
-
- .. _xmlsec1: http://www.aleksey.com/xmlsec/
-
- Now you can install the djangosaml2 package using easy_install or pip. This
- will also install PySAML2 and its dependencies automatically.
-
-
- Configuration
- =============
-
- There are three things you need to setup to make djangosaml2 works in your
- Django project:
-
- 1. **settings.py** as you may already know, it is the main Django
- configuration file.
- 2. **urls.py** is the file where you will include djangosaml2 urls.
- 3. **pysaml2** specific files such as a attribute map directory and a
- certificate.
-
-
- Changes in the settings.py file
- -------------------------------
- The first thing you need to do is add ``djangosaml2`` to the list of
- installed apps::
-
- INSTALLED_APPS = (
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.sites',
- 'django.contrib.messages',
- 'django.contrib.admin',
- 'djangosaml2', # new application
- )
-
- Actually this is not really required since djangosaml2 does not include
- any data model. The only reason we include it is to be able to run
- djangosaml2 test suite from our project, something you should always
- do to make sure it is compatible with your Django version and environment.
-
- .. note::
-
- When you finish the configuation you can run the djangosaml2 test suite
- as you run any other Django application test suite. Just type
- ``python manage.py test djangosaml2``
-
- Then you have to add the djangosaml2.backends.Saml2Backend
- authentication backend to the list of authentications backends.
- By default only the ModelBackend included in Django is configured.
- A typical configuration would look like this::
-
- AUTHENTICATION_BACKENDS = (
- 'django.contrib.auth.backends.ModelBackend',
- 'djangosaml2.backends.Saml2Backend',
- )
-
- .. note::
-
- Before djangosaml2 0.5.0 this authentication backend was
- automatically added by djangosaml2. This turned out to be
- a bad idea since some applications want to use their own
- custom policies for authorization and the authentication
- backend is a good place to define that. Starting from
- djangosaml2 0.5.0 it is now possible to define such
- backends.
-
- Finally we have to tell Django what is the new login url we want to use::
-
- LOGIN_URL = '/saml2/login/'
- SESSION_EXPIRE_AT_BROWSER_CLOSE = True
-
- Here we are telling Django that any view that requires an authenticated
- user should redirect the user browser to that url if the user has not
- been authenticated before. We are also telling that when the user closes
- his browser, the session should be terminated. This is useful in SAML2
- federations where the logout protocol is not always available.
-
- .. note::
-
- The login url starts with ``/saml2/`` as an example but you can change that
- if you want. Check the section about changes in the ``urls.py``
- file for more information.
-
- If you want to allow several authentication mechanisms in your project
- you should set the LOGIN_URL option to another view and put a link in such
- view to the ``/saml2/login/`` view.
-
-
- Changes in the urls.py file
- ---------------------------
-
- The next thing you need to do is to include ``djangosaml2.urls`` module to your
- main ``urls.py`` module::
-
- urlpatterns = patterns(
- '',
- # lots of url definitions here
-
- (r'^saml2/', include('djangosaml2.urls')),
-
- # more url definitions
- )
-
- As you can see we are including ``djangosaml2.urls`` under the *saml2*
- prefix. Feel free to use your own prefix but be consistent with what
- you have put in the ``settings.py`` file in the LOGIN_URL parameter.
-
-
- PySAML2 specific files and configuration
- ----------------------------------------
- Once you have finished configuring your Django project you have to
- start configuring PySAML. If you use just that library you have to
- put your configuration options in a file and initialize PySAML2 with
- the path to that file.
-
- In djangosaml2 you just put the same information in the Django
- settings.py file under the SAML_CONFIG option.
-
- We will see a typical configuration for protecting a Django project::
-
- from os import path
- import saml2
- BASEDIR = path.dirname(path.abspath(__file__))
- SAML_CONFIG = {
- # full path to the xmlsec1 binary programm
- 'xmlsec_binary': '/usr/bin/xmlsec1',
-
- # your entity id, usually your subdomain plus the url to the metadata view
- 'entityid': 'http://localhost:8000/saml2/metadata/',
-
- # directory with attribute mapping
- 'attribute_map_dir': path.join(BASEDIR, 'attribute-maps'),
-
- # this block states what services we provide
- 'service': {
- # we are just a lonely SP
- 'sp' : {
- 'name': 'Federated Django sample SP',
- 'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
- 'endpoints': {
- # url and binding to the assetion consumer service view
- # do not change the binding or service name
- 'assertion_consumer_service': [
- ('http://localhost:8000/saml2/acs/',
- saml2.BINDING_HTTP_POST),
- ],
- # url and binding to the single logout service view
- # do not change the binding or service name
- 'single_logout_service': [
- ('http://localhost:8000/saml2/ls/',
- saml2.BINDING_HTTP_REDIRECT),
- ],
- ('http://localhost:8000/saml2/ls/post',
- saml2.BINDING_HTTP_POST),
- ],
- },
-
- # attributes that this project need to identify a user
- 'required_attributes': ['uid'],
-
- # attributes that may be useful to have but not required
- 'optional_attributes': ['eduPersonAffiliation'],
-
- # in this section the list of IdPs we talk to are defined
- 'idp': {
- # we do not need a WAYF service since there is
- # only an IdP defined here. This IdP should be
- # present in our metadata
-
- # the keys of this dictionary are entity ids
- 'https://localhost/simplesaml/saml2/idp/metadata.php': {
- 'single_sign_on_service': {
- saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SSOService.php',
- },
- 'single_logout_service': {
- saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SingleLogoutService.php',
- },
- },
- },
- },
- },
-
- # where the remote metadata is stored
- 'metadata': {
- 'local': [path.join(BASEDIR, 'remote_metadata.xml')],
- },
-
- # set to 1 to output debugging information
- 'debug': 1,
-
- # certificate
- 'key_file': path.join(BASEDIR, 'mycert.key'), # private part
- 'cert_file': path.join(BASEDIR, 'mycert.pem'), # public part
-
- # own metadata settings
- 'contact_person': [
- {'given_name': 'Lorenzo',
- 'sur_name': 'Gil',
- 'company': 'Yaco Sistemas',
- 'email_address': 'lgs@yaco.es',
- 'contact_type': 'technical'},
- {'given_name': 'Angel',
- 'sur_name': 'Fernandez',
- 'company': 'Yaco Sistemas',
- 'email_address': 'angel@yaco.es',
- 'contact_type': 'administrative'},
- ],
- # you can set multilanguage information here
- 'organization': {
- 'name': [('Yaco Sistemas', 'es'), ('Yaco Systems', 'en')],
- 'display_name': [('Yaco', 'es'), ('Yaco', 'en')],
- 'url': [('http://www.yaco.es', 'es'), ('http://www.yaco.com', 'en')],
- },
- 'valid_for': 24, # how long is our metadata valid
- }
-
- .. note::
-
- Please check the `PySAML2 documentation`_ for more information about
- these and other configuration options.
-
- .. _`PySAML2 documentation`: http://packages.python.org/pysaml2/
-
- There are several external files and directories you have to create according
- to this configuration.
-
- The xmlsec1 binary was mentioned in the installation section. Here, in the
- configuration part you just need to put the full path to xmlsec1 so PySAML2
- can call it as it needs.
-
- The ``attribute_map_dir`` points to a directory with attribute mappings that
- are used to translate user attribute names from several standards. It's usually
- safe to just copy the default PySAML2 attribute maps that you can find in the
- ``tests/attributemaps`` directory of the source distribution.
-
- The ``metadata`` option is a dictionary where you can define several types of
- metadata for remote entities. Usually the easiest type is the ``local`` where
- you just put the name of a local XML file with the contents of the remote
- entities metadata. This XML file should be in the SAML2 metadata format.
-
- The ``key_file`` and ``cert_file`` options references the two parts of a
- standard x509 certificate. You need it to sign your metadata an to encrypt
- and decrypt the SAML2 assertions.
-
- .. note::
-
- Check your openssl documentation to generate a test certificate but don't
- forget to order a real one when you go into production.
-
-
- Custom and dynamic configuration loading
- ........................................
-
- By default, djangosaml2 reads the pysaml2 configuration options from the
- SAML_CONFIG setting but sometimes you want to read this information from
- another place, like a file or a database. Sometimes you even want this
- configuration to be different depending on the request.
-
- Starting from djangosaml2 0.5.0 you can define your own configuration
- loader which is a callable that accepts a request parameter and returns
- a saml2.config.SPConfig object. In order to do so you set the following
- setting::
-
- SAML_CONFIG_LOADER = 'python.path.to.your.callable'
-
-
- User attributes
- ---------------
-
- In the SAML 2.0 authentication process the Identity Provider (IdP) will
- send a security assertion to the Service Provider (SP) upon a succesful
- authentication. This assertion contains attributes about the user that
- was authenticated. It depends on the IdP configuration what exact
- attributes are sent to each SP it can talk to.
-
- When such assertion is received on the Django side it is used to find
- a Django user and create a session for it. By default djangosaml2 will
- do a query on the User model with the 'username' attribute but you can
- change it to any other attribute of the User model. For example,
- you can do this look up using the 'email' attribute. In order to do so
- you should set the following setting::
-
- SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'email'
-
- Please, use an unique attribute when setting this option. Otherwise
- the authentication process will fail because djangosaml2 does not know
- which Django user it should pick.
-
- Another option is to use the SAML2 name id as the username by setting::
-
- SAML_USE_NAME_ID_AS_USERNAME = True
-
- You can configure djangosaml2 to create such user if it is not already in
- the Django database or maybe you don't want to allow users that are not
- in your database already. For this purpose there is another option you
- can set in the settings.py file::
-
- SAML_CREATE_UNKNOWN_USER = True
-
- This setting is True by default.
-
- The other thing you will probably want to configure is the mapping of
- SAML2 user attributes to Django user attributes. By default only the
- User.username attribute is mapped but you can add more attributes or
- change that one. In order to do so you need to change the
- SAML_ATTRIBUTE_MAPPING option in your settings.py::
-
- SAML_ATTRIBUTE_MAPPING = {
- 'uid': ('username', ),
- 'mail': ('email', ),
- 'cn': ('first_name', ),
- 'sn': ('last_name', ),
- }
-
- where the keys of this dictionary are SAML user attributes and the values
- are Django User attributes.
-
- If you are using Django user profile objects to store extra attributes
- about your user you can add those attributes to the SAML_ATTRIBUTE_MAPPING
- dictionary. For each (key, value) pair, djangosaml2 will try to store the
- attribute in the User model if there is a matching field in that model.
- Otherwise it will try to do the same with your profile custom model.
-
- Learn more about Django profile models at:
-
- https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
-
-
- Sometimes you need to use special logic to update the user object
- depending on the SAML2 attributes and the mapping described above
- is simply not enough. For these cases djangosaml2 provides a Django
- signal that you can listen to. In order to do so you can add the
- following code to your app::
-
- from djangosaml2.signals import pre_user_save
-
- def custom_update_user(sender=user, attributes=attributes, user_modified=user_modified)
- ...
- return True # I modified the user object
-
-
- Your handler will receive the user object, the list of SAML attributes
- and a flag telling you if the user is already modified and need
- to be saved after your handler is executed. If your handler
- modifies the user object it should return True. Otherwise it should
- return False. This way djangosaml2 will know if it should save
- the user object so you don't need to do it and no more calls to
- the save method are issued.
-
-
- IdP setup
- =========
- Congratulations, you have finished configuring the SP side of the federation.
- Now you need to send the entity id and the metadata of this new SP to the
- IdP administrators so they can add it to their list of trusted services.
-
- You can get this information starting your Django development server and
- going to the http://localhost:8000/saml2/metadata url. If you have included
- the djangosaml2 urls under a different url prefix you need to correct this
- url.
-
- SimpleSAMLphp issues
- --------------------
- As of SimpleSAMLphp 1.8.2 there is a problem if you specify attributes in
- the SP configuration. When the SimpleSAMLphp metadata parser converts the
- XML into its custom php format it puts the following option::
-
- 'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
-
- But it need to be replaced by this one::
-
- 'AttributeNameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'
-
- Otherwise the Assertions sent from the IdP to the SP will have a wrong
- Attribute Name Format and pysaml2 will be confused.
-
- Furthermore if you have a AttributeLimit filter in your SimpleSAMLphp
- configuration you will need to enable another attribute filter just
- before to make sure that the AttributeLimit does not remove the attributes
- from the authentication source. The filter you need to add is an AttributeMap
- filter like this::
-
- 10 => array(
- 'class' => 'core:AttributeMap', 'name2oid'
- ),
-
- Testing
- =======
-
- One way to check if everything is working as expected is to enable the
- following url::
-
- urlpatterns = patterns(
- '',
- # lots of url definitions here
-
- (r'^saml2/', include('djangosaml2.urls')),
- (r'^test/', 'djangosaml2.views.echo_attributes'),
-
- # more url definitions
- )
-
-
- Now if you go to the /test/ url you will see your SAML attributes and also
- a link to do a global logout.
-
- You can also run the unit tests with the following command::
-
- python tests/run_tests.py
-
- If you have `tox`_ installed you can simply call tox inside the root directory
- and it will run the tests in multiple versions of Python.
-
- .. _`tox`: http://pypi.python.org/pypi/tox
-
- FAQ
- ===
-
- **Why can't SAML be implemented as an Django Authentication Backend?**
-
- well SAML authentication is not that simple as a set of credentials you can
- put on a login form and get a response back. Actually the user password is
- not given to the service provider at all. This is by design. You have to
- delegate the task of authentication to the IdP and then get an asynchronous
- response from it.
-
- Given said that, djangosaml2 does use a Django Authentication Backend to
- transform the SAML assertion about the user into a Django user object.
-
- **Why not put everything in a Django middleware class and make our lifes
- easier?**
-
- Yes, that was an option I did evaluate but at the end the current design
- won. In my opinion putting this logic into a middleware has the advantage
- of making it easier to configure but has a couple of disadvantages: first,
- the middleware would need to check if the request path is one of the
- SAML endpoints for every request. Second, it would be too magical and in
- case of a problem, much harder to debug.
-
- **Why not call this package django-saml as many other Django applications?**
-
- Following that pattern then I should import the application with
- import saml but unfortunately that module name is already used in pysaml2.
-
-
- Changes
- =======
-
- 0.13.0 (2015-02-12)
- -------------------
- - Django 1.7 support. Thanks to Kamei Toshimitsu
-
- 0.12.0 (2014-11-18)
- -------------------
- - Pysaml2 2.2.0 support. Thanks to Erick Tryzelaar
-
- 0.11.0 (2014-06-15)
- -------------------
- - Django 1.5 custom user model support. Thanks to Jos van Velzen
- - Django 1.5 compatibility url template tag. Thanks to bula
- - Support Django 1.5 and 1.6. Thanks to David Evans and Justin Quick
-
- 0.10.0 (2013-05-05)
- -------------------
- - Check that RelayState is not empty before redirecting into a loop. Thanks
- to Sam Bull for reporting this issue.
- - In the global logout process, when the session is lost, report an error
- message to the user and perform a local logout.
-
- 0.9.2 (2013-04-19)
- ------------------
- - Upgrade to pysaml2-0.4.3.
-
- 0.9.1 (2013-01-29)
- ------------------
- - Add a method to the authentication backend so it is possible
- to customize the authorization based on SAML attributes.
-
- 0.9.0 (2012-10-30)
- ------------------
- - Add a signal for modifying the user just before saving it on
- the update_user method of the authentication backend.
-
- 0.8.1 (2012-10-29)
- ------------------
- - Trim the SAML attributes before setting them to the Django objects
- if they are too long. This fixes a crash with MySQL.
-
- 0.8.0 (2012-10-25)
- ------------------
- - Allow to use different attributes besides 'username' to look for
- existing users.
-
- 0.7.0 (2012-10-19)
- ------------------
- - Add a setting to decide if the user should be redirected to the
- next view or shown an authorization error when the user tries to
- login twice.
-
- 0.6.1 (2012-09-03)
- ------------------
- - Remove Django from our dependencies
- - Restore support for Django 1.3
-
- 0.6.0 (2012-08-29)
- ------------------
- - Add tox support configured to run the tests with Python 2.6 and 2.7
- - Fix some dependencies and sdist generation. Lorenzo Gil
- - Allow defining a logout redirect url in the settings. Lorenzo Gil
- - Add some logging calls to improve debugging. Lorenzo Gil
- - Add support for custom conf loading function. Sam Bull.
- - Make the tests more robust and easier to run when djangosaml2 is
- included in a Django project. Sam Bull.
- - Make sure the profile is not None before saving it. Bug reported by
- Leif Johansson
-
- 0.5.0 (2012-05-22)
- ------------------
- - Allow defining custom config loaders. They can be dynamic depending on
- the request.
- - Do not automatically add the authentication backend. This way
- we allow other people to add their own backends.
- - Support for additional attributes other than the ones that get mapped
- into the User model. Those attributes get stored in the UserProfile model.
-
- 0.4.2 (2012-03-23)
- ------------------
- - Fix a crash in the idplist templatetag about using an old pysaml2 function
- - Added a test for the previous crash
-
- 0.4.1 (2012-03-19)
- ------------------
- - Upgrade pysaml2 dependency to version 0.4.1
-
- 0.4.0 (2012-03-18)
- ------------------
- - Upgrade pysaml2 dependency to version 0.4.0 (update our tests as a result
- of this)
- - Add logging calls to make debugging easier
- - Use the Django configured logger in pysaml2
-
- 0.3.3 (2012-02-14)
- ------------------
- - Freeze the version of pysaml2 since we are not (yet!) compatible with
- version 0.4.0
-
- 0.3.2 (2011-12-13)
- ------------------
- - Avoid a crash when reading the SAML attribute that maps to the Django
- username
-
- 0.3.1 (2011-12-01)
- ------------------
- - Load the config in the render method of the idplist templatetag to
- make it more flexible and reentrant.
-
- 0.3.0 (2011-11-30)
- ------------------
- - Templatetag to get the list of available idps.
- - Allow to map the same SAML attribute into several Django field.
-
- 0.2.4 (2011-11-29)
- ------------------
- - Fix restructured text bugs that made pypi page looks bad.
-
- 0.2.3 (2011-06-14)
- ------------------
- - Set a unusable password when the user is created for the first time
-
- 0.2.2 (2011-06-07)
- ------------------
- - Prevent infinite loop when going to the /saml2/login/ endpoint and the user
- is already logged in and the settings.LOGIN_REDIRECT_URL is (badly) pointing
- to /saml2/login.
-
- 0.2.1 (2011-05-09)
- ------------------
- - If no next parameter is supplied to the login view, use the
- settings.LOGIN_REDIRECT_URL as default
-
- 0.2.0 (2011-04-26)
- ------------------
- - Python 2.4 compatible if the elementtree library is installed
- - Allow post processing after the authentication phase by using
- Django signals.
-
- 0.1.1 (2011-04-18)
- ------------------
- - Simple view to echo SAML attributes
- - Improve documentation
- - Change default behaviour when a new user is created. Now their attributes
- are filled this first time
- - Allow to set a next page after the logout
-
- 0.1.0 (2011-03-16)
- ------------------
- - Emancipation from the pysaml package
-
- Keywords: django,pysaml2,saml2,federated authentication,authentication
- Platform: UNKNOWN
- Classifier: Development Status :: 3 - Alpha
- Classifier: Environment :: Web Environment
- Classifier: Intended Audience :: Developers
- Classifier: Operating System :: OS Independent
- Classifier: Programming Language :: Python
- Classifier: Topic :: Internet :: WWW/HTTP
- Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
- Classifier: Topic :: Security
- Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|