跳转到主要内容

一个Flask应用,将单个OpenID Connect发行者包装成Discourse SSO提供者接口。

项目描述

Discourse SSO OIDC桥接器 - 一个Python PyPI包和一个Docker镜像

Latest PyPI version GitHub Workflow Status - Test DockerHub build status

此Python包包含一个Flask应用,部署后可作为Discourse设置SSO时使用的端点。然后它可以包装一个OIDC提供者,避免作为Discourse SSO提供者设置的各种限制

可以使用此仓库中包含并发布到Docker Hub的Docker镜像来部署Flask应用,镜像名称为consideratio/discourse-sso-oidc-bridge

此仓库是在巨人的肩膀上制作的,这些巨人完成了大部分初始工作。感谢 @fmarco76@stevenmirabito 做出的宝贵工作!

我还对Dockerfile进行了优化,这得益于 @greut 的优秀 Medium文章

安装

请注意,这仅安装了一个包含Flask应用的Python包,您必须使用gunicorn或其他WSGI兼容的web服务器来托管它并设置TLS等。

pip install --upgrade discourse-sso-oidc-bridge-consideratio

要启动预构建Docker镜像中的Flask应用,请执行以下操作。

docker run --rm -p 8080:8080 consideratio/discourse-sso-oidc-bridge

实际上使用它时,您应将其部署为对discourse及其用户可访问的方式,以便它可以重定向希望登录的用户。为此,请访问discourse设置并搜索sso

注意:在进行此配置时,您需要检查并填写启用SSOSSO URLSSO密钥。您在SSO密钥中写入的内容应在您的网桥配置中重复。

网桥配置

这些是常见的配置选项,但您可以在default.py中找到一些更奇特的选项。

要配置这些,您有两个选项。

  • 您可以使用基于Python的配置文件,并设置CONFIG_LOCATION环境变量,允许应用程序定位它。

    #######################
    # Flask Configuration #
    #######################
    
    DEBUG = True
    SECRET_KEY = 'my-secret-key-that-i-came-up-with-myself'
    
    # NOTE: Relates to OIDC_SESSION_PERMANENT as well.
    #       https://flask.org.cn/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'
    
  • 您可以使用与配置选项相同名称的环境变量。默认的Python配置将检查这些环境变量,并在可用时使用它们。

配置/环境变量名 描述
DEBUG 在设置此配置时非常有用,因为它会提供大量的额外日志,但同时也包含敏感信息。默认为False
SECRET_KEY Flask的密钥,可以使用openssl rand -hex 32生成。
OIDC_ISSUER OIDC颁发者的URL。为了验证您是否正确获取了它,您可以尝试将其与/.well-known/openid-configuration连接,并查看是否得到各种JSON详细信息而不是404。
OIDC_CLIENT_ID 在您的OIDC颁发者上预先注册的client_id
OIDC_CLIENT_SECRET 为预先注册的OIDC_CLIENT_ID提供的密钥。
OIDC_SCOPE 逗号或空格分隔的OIDC作用域,默认为"openid profile"
OIDC_REDIRECT_URI 您在身份提供者处注册的URL,应包含https://并以/redirect_uri结尾。
OIDC_EXTRA_AUTH_REQUEST_PARAMS 包含要随初始请求一起发送到OIDC提供者的键/值参数的字符串形式的有效JSON对象,默认为"{}"
DISCOURSE_URL 您的Discourse部署的URL,例如"https://discourse.example.com"
DISCOURSE_SECRET_KEY 网桥和Discourse之间共享的密钥,使用openssl rand -hex 32生成。
USERINFO_SSO_MAP 将OIDC用户信息属性名称映射到Discourse SSO属性名称的字符串形式的有效JSON对象。
DEFAULT_SSO_ATTRIBUTES 将Discourse SSO属性映射到默认值的字符串形式的有效JSON对象。默认情况下,sub映射到external_idpreferred_username映射到username
CONFIG_LOCATION 要加载为配置的Python文件的路径,其中可以设置OIDC_ISSUER等。

OIDC提供者配置

您必须从您的OIDC颁发者那里获得client_idclient_secret。颁发者还必须接受将重定向回<PREFERRED_URL_SCHEME>://<bridge_url>/redirect_uri,例如,可以是https://discourse-sso.example.com/redirect_uri

开发笔记

要更改和测试更改

  1. 克隆存储库

  2. 安装依赖项

    pip install -r dev-requirements.txt -r requirements.txt
    
  3. 本地安装包

    pip install -e .
    
  4. 运行测试

    pytest
    

构建并上传PyPI发行版

  1. 运行测试并标记提交。

    # Make sure you dev requirements are up to date
    pip install -r dev-requirements.txt
    
    # Freeze requirements.in to requirements.txt
    pip-compile
    
    # Run tests
    pytest
    
    # Verify that the Dockerfile can build and start
    docker build --tag discourse-sso-oidc-bridge:local . && docker run --rm discourse-sso-oidc-bridge:local
    
    # Tag for the PyPI release automation
    git tag -a $TAG -m "Release $TAG"
    
    # Update changelog manually
    git add .
    git commit -m "Update ChangeLog"
    
  2. 推送Git提交和标签以触发Docker镜像的持续集成和PyPI打包通过GitHub工作流程。

    git push --follow-tags
    
  3. 验证Docker镜像和PyPI包的持续集成。

    访问DockerHub以验证构建成功。

    访问GitHub Actions以验证发布构建成功。

    访问PyPI并发布已发布的发行版。

部署笔记

我已经使用一个更简单的未发布的Helm图表部署了此内容。我很乐意将其开源,作为一个完整的解决方案。但为了避免过度劳累那些对此不太感兴趣的人,我会很高兴如果您通过电子邮件或打开一个问题或类似的问题来显示您的兴趣。

支持者