-
-
Save bureado/5dbddb0bb24bb7c0b447 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
""" | |
This script will help you authenticate a Django application using python-saml with Azure AD. | |
This is sample code. | |
Usage: | |
./script.py <application host> <federation metadata URL> | |
Example: | |
python script.py http://vm.cloudapp.net https://login.microsoftonline.com/95133f51-071a-4531-99b9-5a3b9a116600/federationmetadata/2007-06/federationmetadata.xml > saml/settings.json | |
1. Get and build python-saml from https://github.com/onelogin/python-saml | |
* In Ubuntu, requirements include python-libxml2 libxml2-dev libxmlsec1-dev libpython2.7-dev swig python-django python-lxml python-isodate | |
* Also, sudo pip install untangle to use this script. | |
2. Create your Azure AD domain, a user for testing, and an application | |
* SSO URI is http://fqdn/?sso | |
* ID URI is http://fqdn/metadata/ | |
3. Grab the federation metadata URL for your application (under "View endpoints") | |
4. Use this script to generate a demo-django/saml/settings.json file | |
5. Run python manage.py runserver and browse to http://fqdn/?sso | |
""" | |
import untangle | |
import base64 | |
import re | |
import json | |
import sys | |
from subprocess import Popen, PIPE, STDOUT | |
host = sys.argv[1] | |
addr = sys.argv[2] | |
obj = untangle.parse(addr) | |
svc = obj.EntityDescriptor.IDPSSODescriptor.SingleSignOnService[0]["Location"] | |
der = base64.b64decode(obj.EntityDescriptor.ds_Signature.KeyInfo.X509Data.X509Certificate.cdata) | |
ssl = Popen(["openssl", "x509", "-fingerprint", "-inform", "der", "-noout"], stdout=PIPE, stdin=PIPE) | |
out = ssl.communicate(input=der)[0] | |
bts = out.decode().rstrip().split('=')[1].split(':')[0:20] | |
fin = ''.join(bts).lower() | |
jac = { "url": host + "/?acs", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" } | |
jsl = { "url": host + "/?sls", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" } | |
jsp = { "entityId": host + "/metadata", "assertionConsumerService": jac, "singleLogoutService": jsl, "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" } | |
jso = { "url": svc, "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" } | |
jsu = { "url": svc, "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" } | |
jid = { "entityId": svc, "singleSignOnService": jso, "singleLogoutService": jsu, "certFingerprint": fin } | |
stg = { "strict": "true", "debug": "true", "sp": jsp, "idp": jid } | |
print json.dumps(stg) |
I had to make several changes, notably remove the 'metadata/' suffix from the "issuer", "login" and "logout" URLs.
Thanks for sharing.
FYI, yesterday I got the "metadata.xml" of Azure IDP from our company's administrator, and the data format is a little different.
So I modified the line 43 as following for my circumstance:
der = base64.b64decode(obj.EntityDescriptor.RoleDescriptor[0].KeyDescriptor.KeyInfo.X509Data.X509Certificate.cdata)
to @hobzcalvin @merutak @bureado :
By the way, I just start SSO related work on Python flask+Python3-saml with Azue as IDP, I appreciate if anyone could share me some an complete example of SP.
Thanks!
@gongmingwei did you manage to finish off your SSO/SAML solution? Could you share you experience, or point us new to the area to some resources?
Hi, @ghost I'm also working on getting an Azure SAML SSO + flask + python 3. I'm currently using pysaml2 but I'm getting bad responses from the IDP. Were you able to get your project working?
Thanks for posting this! FYI to get it working, I needed to change
ds_Signature
toSignature
on line 43. The XML returned by the Microsoft endpoint had nods_Signature
element.