[Fixed]-Dropbox and Django SSO using SAML

1👍

Managed to get the functionality I needed using django-saml2-idp https://github.com/peopledoc/django-saml2-idp

Good documentation on installing here: https://github.com/peopledoc/django-saml2-idp/blob/master/doc/INSTALL.txt

Settings in the Dropbox Admin console required the X509 certificate and then the login url set to: https://****.com/idp/login

Note that I had issues installing the M2Crypto dependency so used an Ubuntu package via:
sudo apt-get install python-m2crypto

Additionally I’m using Django 1.9.6 so needed to make overrides to the views.py, urls.py, and registry.py files to make them compatible (various import statements needed updating and the urls changed to the new list format rather than using patterns).

Created a Dropbox Processor as follows:

import base64
import zlib
from saml2idp import base
from saml2idp.xml_render import _get_assertion_xml

def get_assertion_dropbox_xml(parameters, signed=False):
    return _get_assertion_xml(ASSERTION_DROPBOX, parameters, signed)

ASSERTION_DROPBOX = (
    '<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" '
            'ID="${ASSERTION_ID}" '
            'IssueInstant="${ISSUE_INSTANT}" '
            'Version="2.0">'
        '<saml:Issuer>${ISSUER}</saml:Issuer>'
        '${ASSERTION_SIGNATURE}'
        '${SUBJECT_STATEMENT}'
        '<saml:Conditions NotBefore="${NOT_BEFORE}" NotOnOrAfter="${NOT_ON_OR_AFTER}">'
            '<saml:AudienceRestriction>'
                '<saml:Audience>${AUDIENCE}</saml:Audience>'
            '</saml:AudienceRestriction>'
        '</saml:Conditions>'
        '<saml:AuthnStatement AuthnInstant="${AUTH_INSTANT}"'
            '>'
            '<saml:AuthnContext>'
                '<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>'
            '</saml:AuthnContext>'
        '</saml:AuthnStatement>'
        '${ATTRIBUTE_STATEMENT}'
    '</saml:Assertion>'
)


class Processor(base.Processor):

    def _decode_request(self):
        """
        Decodes _request_xml from _saml_request.
        """
        self._request_xml = zlib.decompress(base64.b64decode(self._saml_request), -15)

    def _format_assertion(self):
        self._assertion_xml = get_assertion_dropbox_xml(self._assertion_params, signed=False)

Which you register in your settings.py file as follows:

SAML2IDP_CONFIG = {
    'autosubmit': True,
    'certificate_file': '/****/certificate.pem',
    'private_key_file': '/****/private-key.pem',
    'issuer': 'https://www.****.com',
    'signing': True,
}

sampleSpConfig = {
    'acs_url': 'https://www.dropbox.com/saml_login',
    'processor': 'dropbox.Processor',
}

SAML2IDP_REMOTES = {
    'sample': sampleSpConfig,
}

Works like a dream. Hope this helps somebody out there.

Leave a comment