Discourse OpenID Connect (OIDC)

:discourse2: Summary Discourse OpenID Connect allows an OpenID Connect provider to be used as an authentication provider for Discourse.
:open_book: Install Guide This plugin is bundled with Discourse core. There is no need to install the plugin separately.

Features

The plugin aims to provide a minimal implementation of the specification. Specifically, it supports the “Authorization Code Flow”. To get started, follow the plugin installation instructions, or contact your hosting provider.

Our oauth2-basic plugin can be used for connecting to some openid-connect providers (OpenID Connect is based on OAuth2). However, this plugin should require far less manual configuration, and can make use of the JWT “ID Token” if a JSON API is not available.

Configuration is automatically performed using an OpenID Connect Discovery Document. According to the specification, this should be located at <issuer domain>/.well-known/openid-configuration, but Discourse supports any path to allow for non-compliant implementations (e.g. Azure B2C). The discovery document is cached for 10 minutes, to improve performance on high-traffic sites.

If the discovery document includes a userinfo_endpoint parameter, then the plugin will use that to collect user metadata. If not, the plugin will extract metadata from the id_token (A JWT) supplied by the token endpoint. The plugin DOES NOT verify the authenticity of the JWT signature, as this would significantly increase complexity. This decision is supported by the specification:

If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature.

Configuration

Basic Configuration Options

  • openid_connect_enabled: Enable OpenID Connect authentication

  • openid_connect_discovery_document: OpenID Connect discovery document URL. Normally located at https://your.domain/.well-known/openid-configuration

  • openid_connect_client_id: OpenID Connect client ID

  • openid_connect_client_secret: OpenID Connect client secret

  • openid connect rp initiated logout: Redirect the user to end_session_endpoint after logout. Must be supported by your identity provider and included in the discovery document.

  • openid connect rp initiated logout redirect: (optional) The post_logout_redirect_uri which will be passed to the logout endpoint. If provided, it must be registered with the identity provider.

  • openid_connect_authorize_scope: The scopes sent to the authorize endpoint. This must include ‘openid’

  • openid_connect_use_pkce: Enable Proof Key for Code Exchange (PKCE) for OpenID Connect authentication.

  • openid_connect_verbose_logging: Log detailed openid-connect authentication information to /logs. Keep this disabled during normal use.

Advanced Configuration Options

  • openid_connect_token_scope: The scopes sent when requesting the token endpoint. The official specification does not require this.

  • openid_connect_error_redirects: If the callback error_reason contains the first parameter, the user will be redirected to the URL in the second parameter. Used for unusual implementations that send errors in response to user input (e.g. Azure B2C)

  • openid_connect_allow_association_change: Allow users to disconnect and reconnect their Discourse accounts from the OpenID Connect provider

Example setup

Here we will set up the openid-connect plugin to connect to Google’s OpenID Connect provider. This replicates functionality that already exists in the core of Discourse, but it serves as an accessible example.

  1. Head to OpenID Connect  |  Sign in with Google  |  Google for Developers and follow the instructions to obtain OAuth Credentials.

  2. On the same page, follow the instructions to add a redirect URI. This should be https://<your_forum>/auth/oidc/callback (without a trailing slash)

  3. Go to your Discourse site settings and search for “openid_connect”

    • openid connect enabled:

    • openid connect discovery document: https://accounts.google.com/.well-known/openid-configuration

    • openid connect client id: <client-id>

    • openid connect client secret: <client-secret>

    • openid connect authorize scope: openid email (with a space in between)

  4. You’re done. The “Login with OpenID Connect” button will now log in using Google :tada:. These same steps can be applied to other providers, with very minimal changes.

Debugging

In addition to the verbose_logging setting described above, you can access data about OIDC associations using the data-explorer plugin:

SELECT user_id, provider_name, provider_uid
FROM user_associated_accounts
WHERE provider_name = 'oidc'

Or on the rails console:

User.find_by_username("david").user_associated_accounts.where(provider_name: 'oidc')

Provider Specific Notes

Please feel free to update this if you find any provider-specific quirks relating to this integration:

Entra ID (formerly Azure AD)

Add the email scope, and make sure you’re using the version 2 endpoint configuration document. For example

https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration
Azure B2C

The discovery document URL details can be found here: Web sign in with OpenID Connect - Azure AD B2C | Microsoft Learn

To make emails work:

Yahoo
  1. Head to Login - Sign in to Yahoo and create a new app

  2. Enter the Application Name, and set the callback domain to your forum domain (e.g. meta.discourse.org)

  3. Under API Permissions, choose Profiles: Read/Write Public and Private. This is the only way I know of to obtain the user email address

  4. Save the app

  5. In the Discourse OIDC settings, set the discovery document to

    https://login.yahoo.com/.well-known/openid-configuration
    
  6. Enter the client ID and secret from Yahoo

  7. Enable the OIDC plugin

AWS Cognito
  1. Go to Cognito and select or create a new user pool.
  2. Define an app in App clients.
  3. Leave everything to default, but change Auth Flows Configuration to only select ALLOW_REFRESH_TOKEN_AUTH.
  4. Go to app client settings and select the new app.
  5. Change the callback URL to https://yoursite.example.com/auth/oidc/callback.
  6. Only check the Authorization code grant flow among “Allowed OAuth Flows”.
  7. Check all scopes needed (I have all checked).
Okta
  1. Configure Discourse with your Okta app client ID and secret

  2. Set the discovery document URL to

    https://{your-app}.okta.com/.well-known/openid-configuration
    
  3. In Discourse, set the openid connect authorize scope to openid email

:discourse2: Hosted by us? This plugin is available on our Business and Enterprise plans. OAuth 2.0 & OpenID Connect Support | Discourse - Civilized Discussion

Last edited by @pedro 2025-08-29T23:26:31Z

Check documentPerform check on document:
51 个赞

您好,

我们正在 AWS 上的 Discourse 安装中使用 OpenID Connect Authentication Plugin。
我们已经部署了 Discourse、Discourse Sidekiq 和 Redis 容器(基于 Bitnami,但请不要赶我走 ;))。数据库运行在 AWS RDS 上。我们使用 KeyCloak。

一切都在运行。

但有时在重启 Discourse AWS 任务后,会出现这种情况:它认为它在缓存中有发现文档,但实际上那里没有文档。而且它不会尝试从 KeyCloak 重新检索它:

OIDC Log: Discovery document loaded from cache
OIDC Log: Discovery document is
---
(oidc) Request phase initiated.
(oidc) Authentication failure! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Discovery document is missing

在浏览器应用程序中,我看到:无法从身份提供商处获取配置。请重试。

您有什么建议吗?

2 个赞

您好,

有没有办法将 Discourse 用户头像源设置为 openID 服务中指定的字段?

编辑:我们正在使用 Keycloak

1 个赞

您好,

我的需求与 @Tomáš_Guba 的类似:我想从用户配置文件的自定义条目中获取值,并在 [custom] 用户字段中使用它。

就我个人而言,我有一个包含 userinfo_endpoint 的发现文档。

插件路线图中是否有类似的功能?

谢谢

1 个赞

您好,我设法让插件与我的SSO openID协同工作,但它没有在其他系统的用户名字段或电子邮件等字段中填入信息……

我想我应该在“openid connect claims”字段中进行一些配置,但我不知道如何直接配置该字段。有人能给我举个例子吗?这是我项目的一些截图:
https://imgur.com/gallery/LWvkJUV

1 个赞

登录私人帖子时,是否有办法避免“丢失”原始路线?

如果我们访问一个私人页面并点击该页面上的任一登录按钮,当重定向回网站时,我们会最终停留在分类页面。

您好 @david

您能否查看帖子中提到的问题?我想在 OAuth 的基础上使用 OIDC 插件。但我遇到了同样的问题——无法将参数传递给 /authorize 请求。我以 foo=bar 的格式将值放入插件中。

我无法在 LinkedIn 上让它正常工作。有人遇到过这种情况吗?当我点击“使用…登录”按钮并“允许”我的应用程序使用我的 LinkedIn 电子邮件后,我会被重定向到 LinkedIn 并成功登录,然后出现“抱歉,授权您的帐户时出错。请重试。”的提示。

https:/discourse.mysite.com/auth/failure?message=invalid_credentials&origin=https%3A%2F%2Fdiscourse.mysite.com%2F&strategy=oidc

我仍然对此有问题。我收到以下错误:

(oidc) 身份验证失败!invalid_credentials: OAuth2::Error, invalid_request: 缺少必需的参数“client_secret” {“error”:“invalid_request”,“error_description”:“必需的参数

这是 omniauth 错误,似乎与此有关 [可能]: No longer works with oauth2 gem v2.0+ · Issue #68 · decioferreira/omniauth-linkedin-oauth2 · GitHub

非常感谢您的帮助!

我收到以下错误:

(oidc) 身份验证失败!openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Discovery document is missing

OIDC 日志:获取发现文档时引发错误 Faraday::ConnectionFailed FinalDestination: lookup failed

我在管理员设置中将插件设置“openid connect discovery document”设置为:https://<auth_provider>/.well-known/openid-configuration,并且我可以在运行的应用程序 Docker 容器中使用 Curl 命令甚至在 Rails 控制台中成功访问它。

有什么想法为什么我会收到这些错误吗?因为这个无法正确集成。另外,我位于内网,并使用公司代理,如果这对您有帮助的话。就像我说的,在容器的环境变量中启用代理后,我可以正确访问“openid connect discovery document”网址。

1 个赞

2 篇帖子已拆分到一个新主题:允许多个 OIDC 源

帖子已拆分为新主题:使用 OIDC 覆盖头像

您好!

新问题:此插件是否处理会话管理?(https://openid.net/specs/openid-connect-session-1_0.html)。
我认为不是,因为即使 OP 发送了 session_state 数据,我在代码中也看不到任何将其存储为 cookie 或类似内容的地方。

所以这是一个问题/功能请求 :slight_smile: 这将是极好的!

2 个赞

当使用此插件和 AWS Cognito 时,要注销,Cognito 要求将 client_id 参数传递到注销 URL。据我所知,没有办法向注销 URL 添加其他查询参数——是这样吗?如果不是,是否可以添加此功能?

嘿,各位 :wave:t3:

我为这个插件写了一个小扩展(技术上是以主题/组件的形式),用于隐藏登录弹出窗口中的“通过 OIDC 登录”按钮,但可以通过访问特殊 URL 来启动通过 OIDC 的登录流程。

discourse-autooidc.zip (1.0 KB)

此功能用例是为我们公司的成员提供安全便捷(自动)的 OAuth 登录,而无需公开指向 OAuth 提供商(在我们的例子中是 Authentik,但也应该适用于 Authelia、Keycloak、Auth0、Okta 等)的链接,并且不会打扰所有其他永远无法或不应使用通过 OIDC 登录按钮的用户。

要通过 OIDC 登录,只需调用 https://<your-discourse-base-url>/login#autooidc

3 个赞

您可能对 GitHub - discourse/discourse-hide-auth-method: A theme component which allows hiding a specific login method from the UI, without fully disabling it 感兴趣,它的功能与之类似

3 个赞

Keycloak 支持 Backchannel logout URL

当注销请求发送到此领域(通过 end_session_endpoint)时,将导致客户端自行注销的 URL。如果省略,在这种情况下将不会向客户端发送注销请求。

如果此插件公开某个端点,接受来自 Keycloak 的有效负载并立即将会话中的某个用户注销,那就太好了。否则,当我们在 Keycloak 中禁用用户时,我们必须等待 maximum session age(默认值相当大)。

您也可以通过用户的管理页面(例如 /admin/-1/system)将他们从所有会话中注销,然后点击页面顶部的 Log Out 按钮。

您好,

当发现文档获取失败时(例如,发生超时),插件会缓存错误,这意味着身份验证在 10 分钟内不可用。是否可以不缓存错误,以便更早地重试获取?

此致

抱歉打扰,但有一个针对此的开放 PR,合并它以添加 PKCE 支持应该很容易。

@nbianca 我看到您是该存储库的最新提交者,您能看一下吗?:folded_hands:

1 个赞