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 Me gusta

Hola,\n\nestamos utilizando el plugin de autenticación OpenID Connect con una instalación de Discourse en AWS.\nHemos implementado los contenedores Discourse, Discourse Sidekiq y Redis (basado en Bitnami, pero por favor no me echen ;). La base de datos se ejecuta en AWS RDS. Usamos KeyCloak.\n\nLas cosas funcionan.\n\nPero a veces, después de reiniciar la Tarea de AWS de Discourse, sucede que cree que tiene el documento de descubrimiento en la caché, pero luego no hay ningún documento allí. Y no intenta recuperarlo de KeyCloak:\n\n\n\nOIDC Log: Discovery document loaded from cache\nOIDC Log: Discovery document is\n---\n(oidc) Request phase initiated.\n(oidc) Authentication failure! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Discovery document is missing\n\nEn la aplicación del navegador veo: No se puede obtener la configuración del proveedor de identidad. Por favor, inténtelo de nuevo.\n\n¿Qué puedes aconsejar?

2 Me gusta

Hola,

¿Hay alguna forma de establecer la fuente del avatar del usuario de Discourse en un campo especificado en el servicio openID?

Editar: estamos usando keycloak

1 me gusta

Hola,

Tengo un requisito similar al de @Tomáš_Guba: me gustaría obtener un valor de una entrada personalizada en el perfil del usuario y usarlo en un campo de usuario [personalizado].

En mi caso particular, tengo un documento de descubrimiento con un userinfo_endpoint.

¿Hay algo así en la hoja de ruta del plugin?

Gracias

1 me gusta

Hola, logré hacer funcionar el plugin con mi openID SSO pero no me viene rellenado el campo username del otro sistema ni el email entre otros campos…

Me imagino que debería configurar algo en el campo “openid connect claims”, pero no se como configurar este campo directamente. ¿Alguien me puede poner un ejemplo? Aquí os dejo unas capturas de como tengo mi proyecto:
https://imgur.com/gallery/LWvkJUV

1 me gusta

¿Hay alguna forma de evitar “perder” la ruta original al iniciar sesión en una publicación privada?

Si visitamos una página privada y hacemos clic en cualquiera de los botones de inicio de sesión en esa página, al ser redirigidos de nuevo al sitio, terminamos en la página de categorías.

Hola @david,

¿Puedes echar un vistazo al problema mencionado en la siguiente publicación? Me gustaría usar el plugin OIDC sobre OAuth básico. Pero me enfrento al mismo problema: no puedo pasar parámetros a la solicitud /authorize. Pongo el valor en el plugin en formato foo=bar.

No he podido hacer que esto funcione en LinkedIn. ¿Alguien más lo ha intentado? Llego hasta el inicio de sesión en LinkedIn después de ser redirigido allí al hacer clic en el botón “iniciar sesión con…” y luego “permitir” que mi aplicación use mi correo electrónico de LinkedIn, luego me aparece “Lo sentimos, hubo un error al autorizar su cuenta. Por favor, inténtelo de nuevo”.

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

Todavía tengo problemas con esto. Estoy recibiendo el siguiente error:

(oidc) Fallo de autenticación! invalid_credentials: OAuth2::Error, invalid_request: Falta un parámetro requerido "client_secret" {"error":"invalid_request","error_description":"A required parameter

Es un error de omniauth y parece estar relacionado [potencialmente] con esto: No longer works with oauth2 gem v2.0+ · Issue #68 · decioferreira/omniauth-linkedin-oauth2 · GitHub

¡Se agradece la ayuda!

Recibo los siguientes errores:


(oidc) ¡Fallo de autenticación! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, el documento de descubrimiento falta

Registro OIDC: la obtención del documento de descubrimiento generó un error Faraday::ConnectionFailed FinalDestination: la búsqueda falló

Tengo la configuración de mi plugin “documento de descubrimiento de openid connect” establecida en la Configuración de administrador como: https://<auth_provider>/.well-known/openid-configuration y puedo acceder a él con éxito en el contenedor Docker de la aplicación que se está ejecutando con un comando Curl e incluso en la consola de Rails.

¿Alguna idea de por qué recibo estos errores? No puedo integrarme correctamente debido a esto. Además, estoy detrás de la intranet y uso un proxy de la empresa si eso ayuda. Como dije, con el proxy habilitado en el ENV del contenedor, puedo acceder correctamente a la URL del “documento de descubrimiento de openid connect”.

1 me gusta

2 publicaciones se dividieron en un nuevo tema: Permitir múltiples fuentes OIDC

Se dividió una publicación en un nuevo tema: Anular avatares con OIDC

Hola!

Nueva pregunta: ¿este plugin maneja la gestión de sesiones? (Final: OpenID Connect Session Management 1.0).
No creo que sea así porque, incluso si el OP envía los datos de session_state, no veo en ninguna parte del código dónde se almacena como una cookie o algo similar.

Así que esto es una pregunta/solicitud de función :slight_smile: ¡Sería fantástico!

2 Me gusta

Al usar este plugin con AWS Cognito, para cerrar sesión, Cognito requiere pasar un parámetro client_id a la URL de cierre de sesión. Por lo que he podido averiguar, no hay forma de añadir parámetros de consulta adicionales a la URL de cierre de sesión, ¿es correcto? Si no es así, ¿es posible añadir esta capacidad?

Hola a todos :wave:t3:

He escrito una pequeña extensión para este plugin (técnicamente en forma de tema/componente) para ocultar el botón “Iniciar sesión a través de OIDC” en la ventana emergente de inicio de sesión, pero iniciar el flujo de inicio de sesión a través de OIDC accediendo a una URL especial.

discourse-autooidc.zip (1,0 KB)

El caso de uso para esta función es proporcionar un inicio de sesión seguro y conveniente (automático) a través de OAuth para los miembros de nuestra empresa, sin exponer un enlace público al proveedor de OAuth (Authentik en nuestro caso, pero también debería funcionar con Authelia, Keycloak, Auth0, Okta,…) y sin molestar a todos los demás usuarios con un botón de inicio de sesión a través de OIDC que nunca podrán o deberían usar.

Para iniciar sesión a través de OIDC, simplemente llame a https://<tu-url-base-de-discourse>/login#autooidc

3 Me gusta

Puede que te interese GitHub - discourse/discourse-hide-auth-method: A theme component which allows hiding a specific login method from the UI, without fully disabling it, que hace algo similar

3 Me gusta

Keycloak admite la URL de cierre de sesión del canal posterior:

URL que provocará que el cliente cierre su propia sesión cuando se envíe una solicitud de cierre de sesión a este realm (a través de end_session_endpoint). Si se omite, no se enviará ninguna solicitud de cierre de sesión al cliente en este caso.

Sería genial si este plugin expusiera algún endpoint que acepte la carga útil de Keycloak y cierre la sesión de algún usuario de todas las sesiones inmediatamente. De lo contrario, cuando deshabilitamos al usuario en Keycloak, debemos esperar la edad máxima de la sesión (que es bastante grande por defecto).

También podrías cerrarles la sesión de todas las sesiones usando la página de administración del usuario (por ejemplo, /admin/-1/system) y hacer clic en el botón Log Out en la parte superior de la página.

Hola,

Cuando la obtención del documento de descubrimiento falla (por ejemplo, cuando hay un tiempo de espera agotado), el plugin almacena en caché el error, lo que significa que la autenticación no está disponible durante 10 minutos. ¿Es posible no almacenar en caché el error para que la obtención se reintente antes?

Saludos

Disculpa la interrupción, pero hay una PR abierta para esto que debería ser trivial de fusionar para añadir soporte PKCE.

@nbianca Vi que eras el último en confirmar en el repositorio, ¿podrías echarle un vistazo, quizás? :folded_hands:

1 me gusta