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 « J'aime »

Salut,\nnous utilisons le plugin d’authentification OpenID Connect avec une installation Discourse sur AWS. \nNous avons déployé les conteneurs Discourse, Discourse Sidekiq et Redis (basés sur Bitnami, mais ne me chassez pas ;)). La base de données fonctionne sur AWS RDS. Nous utilisons KeyCloak.\n\nLes choses fonctionnent.\n\nMais parfois, après un redémarrage de la tâche Discourse AWS, il arrive qu’il pense avoir le document de découverte dans le cache, mais qu’il n’y ait pas de document. Et il n’essaie pas de le récupérer à nouveau 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\nDans l’application du navigateur, je vois : Impossible de récupérer la configuration auprès du fournisseur d’identité. Veuillez réessayer.\n\nQue pouvez-vous conseiller ?

2 « J'aime »

Bonjour,

Y a-t-il un moyen de définir la source de l’avatar de l’utilisateur Discourse sur un champ spécifié dans le service OpenID ?

Modification : nous utilisons Keycloak

1 « J'aime »

Bonjour,

J’ai une exigence similaire à celle de @Tomáš_Guba : j’aimerais récupérer la valeur d’une entrée personnalisée dans le profil utilisateur et l’utiliser dans un champ utilisateur [personnalisé].

Dans mon cas personnel, j’ai un document de découverte avec un userinfo_endpoint.

Y a-t-il quelque chose comme ça dans la feuille de route du plugin ?

Merci

1 « J'aime »

Bonjour, j’ai réussi à faire fonctionner le plugin avec mon SSO openID mais il ne remplit pas le champ nom d’utilisateur du système cible ni l’e-mail, entre autres champs…

J’imagine que je devrais configurer quelque chose dans le champ « openid connect claims », mais je ne sais pas comment configurer ce champ directement. Quelqu’un peut-il me donner un exemple ? Voici quelques captures d’écran de mon projet :
https://imgur.com/gallery/LWvkJUV

1 « J'aime »

Existe-t-il un moyen d’éviter de « perdre » l’itinéraire d’origine lors de la connexion à un article privé ?

Si nous visitons une page privée et cliquons sur l’un des boutons de connexion sur cette page, lorsque nous sommes redirigés vers le site, nous nous retrouvons sur la page des catégories.

Salut @david,

Pouvez-vous s’il vous plaît examiner le problème mentionné dans le post suivant ? Je voudrais utiliser le plugin OIDC sur OAuth basic. Mais je rencontre le même problème - impossible de passer des paramètres à la requête /authorize. J’ai mis la valeur dans le plugin au format foo=bar.

Je n’ai pas réussi à faire fonctionner cela sur LinkedIn. Quelqu’un d’autre a-t-il essayé ? J’arrive à me connecter à LinkedIn après y avoir été redirigé en cliquant sur le bouton “se connecter avec…” puis en “autorisant” mon application à utiliser mon e-mail de LinkedIn, puis je reçois le message “Désolé, une erreur s’est produite lors de l’autorisation de votre compte. Veuillez réessayer.”

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

J’ai toujours du mal avec ça. Je reçois l’erreur suivante :

(oidc) Échec de l'authentification ! invalid_credentials : OAuth2::Error, invalid_request : Un paramètre requis « client_secret » est manquant {\"error\":\"invalid_request\",\"error_description\":\"A required parameter

C’est une erreur omniauth et elle semble liée [potentiellement] à ceci : No longer works with oauth2 gem v2.0+ · Issue #68 · decioferreira/omniauth-linkedin-oauth2 · GitHub

Toute aide est appréciée !

Je reçois les erreurs suivantes :


(oidc) Échec de l'authentification ! openid_connect_discovery_error : OmniAuth::OpenIDConnect::DiscoveryError, le document de découverte est manquant

Journal OIDC : La récupération du document de découverte a généré une erreur Faraday::ConnectionFailed FinalDestination : échec de la recherche

J’ai configuré mon plugin “document de découverte openid connect” dans les paramètres d’administration comme suit : https://<auth_provider>/.well-known/openid-configuration et je peux y accéder avec succès dans le conteneur Docker de l’application qui s’exécute avec une commande Curl et même dans la console Rails.

Avez-vous une idée de la raison pour laquelle je reçois ces erreurs ? Je ne peux pas m’intégrer correctement à cause de cela. De plus, je suis derrière l’intranet et j’utilise un proxy d’entreprise si cela peut aider. Comme je l’ai dit, avec le proxy activé dans l’ENV du conteneur, je peux accéder correctement à l’URL du “document de découverte openid connect”.

1 « J'aime »

2 messages ont été déplacées vers un nouveau sujet : Autoriser plusieurs sources OIDC

Un message a été divisé dans un nouveau sujet : Remplacer les avatars avec OIDC

Bonjour !

Nouvelle question : ce plugin gère-t-il la gestion des sessions ? (Final: OpenID Connect Session Management 1.0).
Je ne pense pas car même si l’OP envoie les données session_state, je ne vois nulle part dans le code où elles sont stockées sous forme de cookie ou autre.

C’est donc une question/demande de fonctionnalité :slight_smile: Ce serait formidable !

2 « J'aime »

Lorsque vous utilisez ce plugin avec AWS Cognito, pour vous déconnecter, Cognito exige de passer un paramètre client_id à l’URL de déconnexion. D’après ce que je peux comprendre, il n’y a aucun moyen d’ajouter des paramètres de requête supplémentaires à l’URL de déconnexion - est-ce exact ? Sinon, est-il possible d’ajouter cette fonctionnalité ?

Salut tout le monde :wave:t3:

J’ai écrit une petite extension à ce plugin (techniquement sous la forme d’un thème/composant) - pour masquer le bouton « Se connecter via OIDC » dans la fenêtre contextuelle de connexion, mais pour lancer le flux de connexion via OIDC en accédant à une URL spéciale.

discourse-autooidc.zip (1,0 Ko)

Le cas d’utilisation de cette fonctionnalité est de fournir une connexion sécurisée et pratique (automatique) via OAuth aux membres de notre entreprise, sans exposer de lien public vers le fournisseur OAuth (Authentik dans notre cas, mais devrait également fonctionner avec Authelia, Keycloak, Auth0, Okta,…) et sans gêner tous les autres utilisateurs avec un bouton de connexion via OIDC qu’ils ne peuvent ou ne devraient jamais utiliser.

Pour vous connecter via OIDC, il suffit d’appeler https://<votre-url-de-base-discourse>/login#autooidc

3 « J'aime »

Vous pourriez être intéressé par GitHub - discourse/discourse-hide-auth-method: A theme component which allows hiding a specific login method from the UI, without fully disabling it, qui fait quelque chose de similaire

3 « J'aime »

Keycloak prend en charge l’URL de déconnexion Backchannel :

URL qui amènera le client à se déconnecter lui-même lorsqu’une requête de déconnexion est envoyée à ce realm (via end_session_endpoint). Si omis, aucune requête de déconnexion ne sera envoyée au client dans ce cas.

Ce serait formidable si ce plugin exposait un point de terminaison qui accepte la charge utile de Keycloak et déconnecte immédiatement un utilisateur de toutes les sessions. Sinon, lorsque nous désactivons un utilisateur dans Keycloak, nous devons attendre la durée de vie maximale de la session (qui est assez grande par défaut).

Vous pouvez également les déconnecter de toutes les sessions en utilisant la page d’administration de l’utilisateur (par exemple, /admin/-1/system) et cliquer sur le bouton Se déconnecter en haut de la page.

Bonjour,

Lorsque la récupération du document de découverte échoue (par exemple, en cas de délai d’attente), le plugin met en cache l’erreur, ce qui signifie que l’authentification est indisponible pendant 10 minutes. Est-il possible de ne pas mettre en cache l’erreur afin que la récupération soit retentée plus tôt ?

Cordialement

Désolé pour le ping, mais il y a une PR ouverte pour cela qui devrait être triviale à fusionner pour ajouter la prise en charge de PKCE.

@nbianca J’ai vu que vous étiez le dernier committer du dépôt, pourriez-vous y jeter un œil, peut-être ? :folded_hands:

1 « J'aime »