The way to integrate SAML into Django, indeed to integrate most Single Sign On/Identity provider solutions into most python based websites (Sorry, Service Providers) is to use Python Social Auth.
We need to ensure the following are installed in the environment
I did read that the saml extra is required for python-social-auth which is installed using
but that didn’t do anything extra when I tried it.
And python3-saml requires the following packages to be installed:
The list of authentication backends in
settings.py needs to include
SAMLAuth as follows:
Looking at the details returned by Raven (These differ by identity provider), when I log in I see the following, which is explained in the SAML Attributes documentation for Raven:
|‘urn:oid:220.127.116.11.4.1.5918.104.22.168.10’||Anonymous identfier. This is a dictionary of data.|
|‘urn:oid:22.214.171.124.4.1.59126.96.36.199.6’||[‘email@example.com’]||Principal Name. This looks like an email address, but shouldn’t be used as one.|
|‘urn:oid:188.8.131.52.4.1.59184.108.40.206.6-eppn-nameid’||[‘firstname.lastname@example.org’]||I am not sure how different this is from above.|
|‘urn:oid:220.127.116.11.4.1.5918.104.22.168.9’||[‘email@example.com’]||Scoped affiliation. So I am in the University directory.|
In particular it doesn’t include my name. This is probably because I specified a .local address for my website rather than .cam.ac.uk. We should note all of these are returned in python lists, even if there is only one value.
So to create a userid I need to specify the key name above -
email address to be used to create my local account.
The entries which were in the json file in the previous post need to go into
settings.py as follows. I am
using the same certificate and key as before as this is still running on my desktop.
An issue I discovered here is that the language is
en-US whereas I had specified
which caused an error. I notice
en-GB works as well, and so does just
en by itself - maybe I should use that.
Once all this has been filled in we are ready to create the view to generate the metadata
to register ourselves at the identity provider. I found the missing imports a little
confusing, but I got there in the end. I added the following to
This generates a very similar XML document fragment to before. Since I am using the same
certificate I thought the previous one should work again, but it didn’t. So I had to edit it again
as before to add in the XML namespace definitions for
md in the
ds in the
KeyInfo tag. See my previous post if this doesn’t make sense.
Configuring the Application
There is some more work to set up Django. Another page on the
I have to make the system automatically select the Identity Provider to log in when
attempting to access a protected page. To do this, I need to set the following in
raven is what I called the identity provider in the
To automatically create a user in Django once authenticated by Raven, I do the following in
Actually I don’t need to do this it is the default as mentioned in the
Another thing that isn’t required, but might be later on is to ensure only users from Cambridge can authenticate. We do this by whitelisting the Cambridge domain as follows:
The nice thing about this is that any views that require protecting
just need to have the
@login_required decorator to be applied. When the user tries to access
a page containing such a view when they are not logged in, they are redirected to SSO and logged in
The ID provider said my website wasn’t configured. When I looked at the application metadata I realised it was because the entityID was set to the hostname of the VM running the application rather than the hostname the application would be given through the load balancer. I fixed this in settings.py by changeing the following: