Package: discourse-sso-oidc-bridge-consideratio
Discourse SSO OIDC Bridge - A Python PyPI package and a Docker imageThis Python package contains a Flask application that when deployed can be used
as and endpoint for Discourse when setting up it's SSO. It will then be able to
wrap a OIDC provider and avoid variouslimitationsof not being setup as a Discourse SSO provider.The Flask application can be deployed using a Docker image that is also within
this repo and published to docker hub asconsideratio/discourse-sso-oidc-bridge.This repo was made standing on the shoulders giants who made most of the initial
work. Thank you@fmarco76and@stevenmirabitofor the valuable work
you have made!https://github.com/fmarco76/DiscourseSSOhttps://github.com/ComputerScienceHouse/DiscourseOIDCI also did some Dockerfile refinements thanks to@greut's excellentMedium
article.InstallationNote that this only installs a Python package containing a Flask application,
you must usegunicornor another WSGI compatible webserver to host it and
setup TLS etc.pipinstall--upgradediscourse-sso-oidc-bridge-consideratioTo startup a the Flask app within a prebuilt Docker image, do the following.dockerrun--rm-p8080:8080consideratio/discourse-sso-oidc-bridgeTo actually use it, you should make it deployed in a way that it is accessible
for discourse and its users, so it can redirect arriving users who wants to
login to it. To do this, visit the discourse settings and search forsso.NOTE:When you do this setup, you want to check and fill inenable sso,sso url, andsso secret. What you write in yoursso secretshould be
repeated in your bridge configuration.Bridge ConfigurationThese are common configuration options, but you can find some more exotic ones withindefault.py.To configure these, you have two options.You can provide provide a Python based config file and set theCONFIG_LOCATIONenvironment variable allowing the application to locate it.######################## Flask Configuration ########################DEBUG=TrueSECRET_KEY='my-secret-key-that-i-came-up-with-myself'# NOTE: Relates to OIDC_SESSION_PERMANENT as well.#       http://flask.pocoo.org/docs/1.0/config/#PERMANENT_SESSION_LIFETIME# NOTE: You may want to learn about the "maximum session age" setting in discourse#       as well.# PERMANENT_SESSION_LIFETIME = 2678400################################# OpenID Connect Configuration ################################## NOTE: Relates to PERMANENT_SESSION_LIFETIME as well.#       https://github.com/zamzterz/Flask-pyoidc#flask-configuration# OIDC_SESSION_PERMANENT = True# NOTE: If you add /.well-known/openid-configuration to your OIDC_ISSUER, you should get a bunch of JSON details back if you got it right.OIDC_ISSUER='https://my-oidc-provider.com'OIDC_CLIENT_ID='my-client-id-from-my-oidc-provider'OIDC_CLIENT_SECRET='my-secret-key-from-my-oidc-provider'OIDC_SCOPE='openid profile email offline_access'OIDC_REDIRECT_URI='https://discourse-sso.example.com/redirect_uri'############################ Discourse Configuration ############################DISCOURSE_URL='https://discourse.example.com'DISCOURSE_SECRET_KEY='my-other-secret-that-i-came-up-with-myself'You can set environment variables with the same name as the config options.
The default python config will look in these environment variables and use
them if available.Config / ENV nameDescriptionDEBUGVery useful while setting this up as you get lots of additional logs, but also sensitive information. Defaults toFalse.SECRET_KEYA secret for Flask, just generate one withopenssl rand -hex 32.OIDC_ISSUERAn URL to the OIDC issuer. To verify you get this right you can try appending/.well-known/openid-configurationto it and see if you get various JSON details rather than a 404.OIDC_CLIENT_IDA preregisteredclient_idon your OIDC issuer.OIDC_CLIENT_SECRETThe provided secret for the the preregisteredOIDC_CLIENT_ID.OIDC_SCOPEComma or space seperated OIDC scopes, defaults to"openid profile".OIDC_REDIRECT_URIThe URL you register with your identity provider, should includehttps://and end with/redirect_uri.OIDC_EXTRA_AUTH_REQUEST_PARAMSValid JSON object in a string containing key/values for additional parameters to be sent along with the initial request to the OIDC provider, defaults to"{}".DISCOURSE_URLThe URL of your Discourse deployment, example"https://discourse.example.com".DISCOURSE_SECRET_KEYA shared secret between the bridge and Discourse, generate one withopenssl rand -hex 32.USERINFO_SSO_MAPValid JSON object in a string mapping OIDC userinfo attribute names to to Discourse SSO attribute names.DEFAULT_SSO_ATTRIBUTESValid JSON object in a string mapping Discourse SSO attributes to default values. By defaultsubis mapped toexternal_idandpreferred_usernametousername.CONFIG_LOCATIONThe path to a Python file to be loaded as config whereOIDC_ISSUERetc. could be set.OIDC Provider ConfigurationYou must have aclient_idandclient_secretfrom your OIDC issuer. The
issuer must also accept redirecting back to<PREFERRED_URL_SCHEME>://<bridge_url>/redirect_uri, which for example could behttps://discourse-sso.example.com/redirect_uri.Development NotesTo make changes and test themClone the repoInstall dependenciespipinstall-rdev-requirements.txt-rrequirements.txtInstall package locallypipinstall-e.Run testspytestBuild and upload a PyPI releaseRun tests and tag a commit.# Make sure you dev requirements are up to datepipinstall-rdev-requirements.txt# Freeze requirements.in to requirements.txtpip-compile# Run testspytest# Verify that the Dockerfile can build and startdockerbuild--tagdiscourse-sso-oidc-bridge:local.&&dockerrun--rmdiscourse-sso-oidc-bridge:local# Tag for the PyPI release automationgittag-a$TAG-m"Release$TAG"# Update changelog manuallygitadd.
gitcommit-m"Update ChangeLog"Push git commits and tags to trigger CD of Docker image and PyPI packaging
through a GitHub workflow.gitpush--follow-tagsVerify CD of Docker image and PyPI package.VisitDockerHubto verify the build succeeds.VisitGitHub
Actionsto verify the release build succeeds.VisitPyPIand
release has been published.Deployment notesI have deployed this using a simpler not published Helm chart. I'm happy to open
source this as well for a complete solution. But to avoid overworking something
that few has interest for it in I'd appreciate if you showed interest in this by
emailing me or opening an issue or similar.