Skip to content

Instantly share code, notes, and snippets.

@dkess
Created June 29, 2018 06:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dkess/cec370a6d76ac11020f1424de646ba1d to your computer and use it in GitHub Desktop.
Save dkess/cec370a6d76ac11020f1424de646ba1d to your computer and use it in GitHub Desktop.
Implementation of Discourse's SSO in Python Flask
# Implementation of Discourse's SSO in Python Flask.
# Assumes username is passed as 'X-WEBAUTH-USER' HTTP header
import base64
import binascii
import hashlib
import hmac
import urllib.parse
from flask import abort, Flask, redirect, request
app = Flask(__name__)
SECRET = 'REPLACE THIS'
# example secret (from their forum post)
#SECRET = b'd836444a9e4084d5b224a60c208dce14'
def h(msg):
return hmac.new(SECRET, msg, digestmod=hashlib.sha256).digest()
@app.route("/")
def do_it():
sso = request.args.get('sso')
sig = request.args.get('sig')
got_sig = h(sso.encode())
if not hmac.compare_digest(binascii.unhexlify(sig), got_sig):
abort(404)
username = request.headers['X-WEBAUTH-USER'].strip()
print(username + ' logged in')
sso_parse = urllib.parse.parse_qs(base64.b64decode(sso).decode())
nonce = sso_parse['nonce'][0]
return_sso_url = sso_parse['return_sso_url'][0]
r = urllib.parse.urlencode({
'require_activation': 'false',
'external_id': username,
'username': username,
'email': username + '@ocf.berkeley.edu',
'nonce': nonce,
})
r64 = base64.b64encode(r.encode())
r2 = {
'sso': r64.decode(),
'sig': binascii.hexlify(h(r64)).decode(),
}
redir_url = return_sso_url + '?' + urllib.parse.urlencode(r2)
return redirect(redir_url, code=302)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment