OpenID Connect (OIDC) pour Discourse

:discourse2: Résumé Discourse OpenID Connect permet d’utiliser un fournisseur OpenID Connect comme fournisseur d’authentification pour Discourse.
:open_book: Guide d’installation Ce plugin est inclus dans le noyau de Discourse. Aucune installation séparée n’est nécessaire.

Fonctionnalités

Le plugin vise à fournir une implémentation minimale de la spécification. Plus précisément, il prend en charge le « flux de code d’autorisation ». Pour commencer, suivez les instructions d’installation du plugin, ou contactez votre hébergeur.

Notre plugin oauth2-basic peut être utilisé pour se connecter à certains fournisseurs OpenID Connect (OpenID Connect est basé sur OAuth2). Cependant, ce plugin nécessite beaucoup moins de configuration manuelle et peut utiliser le « ID Token » JWT si une API JSON n’est pas disponible.

La configuration est effectuée automatiquement à l’aide d’un document de découverte OpenID Connect. Selon la spécification, celui-ci devrait se trouver à <domaine_d'émetteur>/.well-known/openid-configuration, mais Discourse prend en charge n’importe quel chemin pour permettre des implémentations non conformes (par exemple Azure B2C). Le document de découverte est mis en cache pendant 10 minutes pour améliorer les performances sur les sites à fort trafic.

Si le document de découverte inclut un paramètre userinfo_endpoint, le plugin l’utilisera pour collecter les métadonnées de l’utilisateur. Sinon, le plugin extraira les métadonnées du id_token (un JWT) fourni par le point de terminaison du jeton. Le plugin NE vérifie PAS l’authenticité de la signature JWT, car cela augmenterait considérablement la complexité. Cette décision est soutenue par la spécification :

Si le ID Token est reçu via une communication directe entre le client et le point de terminaison du jeton (ce qui est le cas dans ce flux), la validation du serveur TLS PEUT être utilisée pour valider l’émetteur au lieu de vérifier la signature du jeton.

Pour les fournisseurs d’identité qui prennent en charge l’autorisation sans secret en utilisant le « flux de code d’autorisation avec clé de preuve pour l’échange de code », PKCE doit être activé et la configuration client_secret peut être omise.

Configuration

Options de configuration de base

  • openid_connect_enabled: Activer l’authentification OpenID Connect

  • openid_connect_discovery_document : URL du document de découverte OpenID Connect. Normalement situé à https://votre.domaine/.well-known/openid-configuration

  • openid_connect_client_id : ID du client OpenID Connect

  • openid_connect_client_secret : Secret du client OpenID Connect

  • openid connect rp initiated logout : Rediriger l’utilisateur vers end_session_endpoint après la déconnexion. Doit être pris en charge par votre fournisseur d’identité et inclus dans le document de découverte.

  • openid connect rp initiated logout redirect : (facultatif) Le post_logout_redirect_uri qui sera transmis au point de terminaison de déconnexion. Si fourni, il doit être enregistré auprès du fournisseur d’identité.

  • openid_connect_authorize_scope : Les portées envoyées au point de terminaison d’autorisation. Cela doit inclure ‘openid’

  • openid_connect_use_pkce : Activer la clé de preuve pour l’échange de code (PKCE) pour l’authentification OpenID Connect.

  • openid_connect_verbose_logging : Journaliser les informations détaillées d’authentification openid-connect dans /logs. Gardez ceci désactivé lors de l’utilisation normale.

Options de configuration avancées

  • openid_connect_token_scope : Les portées envoyées lors de la demande au point de terminaison du jeton. La spécification officielle ne l’exige pas.

  • openid_connect_error_redirects : Si la raison de l’erreur de rappel contient le premier paramètre, l’utilisateur sera redirigé vers l’URL du second paramètre. Utilisé pour des implémentations inhabituelles qui envoient des erreurs en réponse à une saisie utilisateur (par exemple Azure B2C)

  • openid_connect_allow_association_change : Permettre aux utilisateurs de déconnecter et reconnecter leurs comptes Discourse du fournisseur OpenID Connect

  • openid_connect_groups_claim : Le nom de la revendication dans la réponse OIDC[1] qui contient les groupes de l’utilisateur sous forme de tableau de chaînes. Laissez vide pour désactiver la synchronisation des groupes. Voir Synchronisation des groupes ci-dessous.

  • openid_connect_user_field_mappings : Mappages des revendications OIDC[2] qui seront stockées dans les champs utilisateur de Discourse. Les champs utilisateur sont identifiés par leur ID numérique, que vous pouvez trouver dans l’URL lors de leur édition via le panneau d’administration.

Synchronisation des groupes

Le plugin peut automatiquement synchroniser les adhésions aux groupes de votre fournisseur OpenID Connect avec les groupes Discourse. À chaque connexion, le plugin lira la revendication configurée depuis le jeton OIDC et mettra à jour les adhésions aux groupes de l’utilisateur en conséquence. Pour activer la synchronisation des groupes :

  1. Configurez votre fournisseur d’identité pour retourner un tableau de groupes dans l’une des revendications. Cela doit être un tableau de chaînes.

  2. Définissez openid_connect_groups_claim sur le nom de la revendication dans le jeton OIDC qui contient les groupes de l’utilisateur (par exemple cognito:groups). Une fois défini, cela commencera à synchroniser les informations vers le système « Groupes associés » de Discourse.

  3. Trouvez le groupe Discourse que vous souhaitez lier. Allez dans « Paramètres » > « Adhésion » > « Automatique », puis choisissez les groupes associés à lier. Cette liste déroulante est remplie par les informations du fournisseur d’identité, donc au moins un membre du groupe doit s’être connecté pour qu’une option apparaisse.

Exemple de configuration

Ici, nous allons configurer le plugin openid-connect pour se connecter au fournisseur OpenID Connect de Google. Cela reproduit une fonctionnalité déjà présente dans le noyau de Discourse, mais cela sert d’exemple accessible.

  1. Rendez-vous sur OpenID Connect  |  Sign in with Google  |  Google for Developers et suivez les instructions pour obtenir les identifiants OAuth.

  2. Sur la même page, suivez les instructions pour ajouter une URI de redirection. Celle-ci doit être https://<votre_forum>/auth/oidc/callback (sans barre oblique finale)

  3. Accédez aux paramètres de votre site Discourse et recherchez « openid_connect »

    • openid connect enabled : [x]

    • 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 (avec un espace entre les deux)

  4. C’est tout. Le bouton « Se connecter avec OpenID Connect » vous connectera désormais via Google :tada:. Ces mêmes étapes peuvent être appliquées à d’autres fournisseurs avec des modifications très minimes.

Débogage

En plus du paramètre verbose_logging décrit ci-dessus, vous pouvez accéder aux données sur les associations OIDC en utilisant le plugin data-explorer :

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

Ou dans la console Rails :

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

Notes spécifiques aux fournisseurs

N’hésitez pas à mettre à jour cette section si vous trouvez des particularités spécifiques à un fournisseur liées à cette intégration :

Entra ID (anciennement Azure AD)

Ajoutez la portée email et assurez-vous d’utiliser le document de configuration du point de terminaison version 2. Par exemple

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

Les détails de l’URL du document de découverte se trouvent ici : Web sign in with OpenID Connect - Azure AD B2C | Microsoft Learn

Pour que les e-mails fonctionnent :

Yahoo
  1. Rendez-vous sur https://developer.yahoo.com/apps et créez une nouvelle application

  2. Entrez le nom de l’application et définissez le domaine de rappel sur le domaine de votre forum (par exemple meta.discourse.org)

  3. Sous Autorisations API, choisissez Profils : Lecture/écriture publique et privée. C’est la seule méthode que je connais pour obtenir l’adresse e-mail de l’utilisateur

  4. Enregistrez l’application

  5. Dans les paramètres OIDC de Discourse, définissez le document de découverte sur

    https://login.yahoo.com/.well-known/openid-configuration
    
  6. Entrez l’ID client et le secret de Yahoo

  7. Activez le plugin OIDC

AWS Cognito
  1. Accédez à Cognito et sélectionnez ou créez un nouveau pool d’utilisateurs.
  2. Définissez une application dans les clients d’application.
  3. Laissez tout par défaut, mais modifiez la configuration des flux d’authentification pour sélectionner uniquement ALLOW_REFRESH_TOKEN_AUTH.
  4. Accédez aux paramètres du client d’application et sélectionnez la nouvelle application.
  5. Modifiez l’URL de rappel en https://votresite.example.com/auth/oidc/callback.
  6. Cochez uniquement le flux de délégation de code d’autorisation parmi les « Flux OAuth autorisés ».
  7. Cochez toutes les portées nécessaires (j’ai tout coché).
Okta
  1. Configurez Discourse avec l’ID client et le secret de votre application Okta

  2. Définissez l’URL du document de découverte sur

    https://{votre-app}.okta.com/.well-known/openid-configuration
    
  3. Dans Discourse, définissez openid connect authorize scope sur openid email

:discourse2: Hébergé par nous ? Ce plugin est disponible sur nos offres Business et Enterprise. OAuth 2.0 & OpenID Connect Support | Discourse - Civilized Discussion


  1. token ou charge utile userinfo ↩︎

  2. du token ou de la charge utile userinfo ↩︎

52 « J'aime »
Native SSO with Azure AD
How to setup okta authentication with discourse
Discourse Login using external API
OpenIdAuthenticator plugin fails
Sign in to Discourse using ORCID
Discourse, Keycloak, SAML vs OAuth
OpenID Connect support in selfhosted Discourse instance
How can you connect firebase to discourse?
Keycloak SSO and logout issue
Tutorial for OpenID Connect / Azure AD
OpenID connect plugin
Azure OpenID Connect Authentication Plugin
Installing own gem in plugin
SSO Login page not showing up
Enabling Okta for employees only through OpenID Connect Authentication Plugin
Is "partial" SSO possible?
Auto-sign-in with the OpenId Connect Plugin and AWS Cognito
Official support for Microsoft Azure AD?
CodeBerg support
Availability of OpenID Connect in hosted plans
Can we use the default atlassian id to login to discourse
OpenIdAuthenticator plugin fails
Intergrate Discourse with keycloak
IndieAuth login
Intergrate Discourse with keycloak
Map oidc fields to custom user fields
CSRF problem in development with 'Discourse OpenID Connect' plug-in
Azure B2C SSO to Discourse?
User (patron) getting authorization error message
Memberstack + Webflow + Discourse OpenID Connect
How can add 2 or more discovery documents?
Memberstack + Webflow + Discourse OpenID Connect
Azure AD Authentication and Creation of User Account
Possible to create a Sign in with Ghost plugin for Discourse?
Custom Login Flow: AWS Cognito SSO (via Passwordless Signin) - Is this possible?
Account already in discourse
AAD integration with Discourse
Having trouble setting up AWS Cognito passwordless login
Discourse ID fails to activate on my instance
Restrict Office 365 Login to certain Group
OpenID Connect Plugin not creating new users with AWS Cognito
OIDC users not associating with existing Discourse users
Bundling more popular plugins with Discourse core
OpenID Connect Plugin Refactor (OIDC Implicit Flow)
Availability of OpenID Connect in hosted plans
How to configure the OIDC to set the Username as the email account name or a username like value returned from my auth providers?
Managing group membership via authentication
Failed to bootstrap due to out of memory killer
OAuth connection of discourse
Auto-provisioning user accounts when SSO is enabled
Anyone have a working AWS Cognito configuration w/ ouath2, openid or sso?
SAML Plugin on Self Hosted Discourse
Can I include website analytics in trust data?
Using OpenID Connect with User Flows in Azure B2C
ADFS Authentication
How to set-up Discourse with Atricore Josso CE
Error of Discourse OpenID Connect
How can add 2 or more discovery documents?
./launcher rebuild app fails hard 'bundle exec rake db:migrate' possible issue with github/master repo removal of auth/oath2_authenticator
Removing Yahoo login from Core, and deprecating OpenID 2.0
SSO with TownNews CMS
OpenID Connect Plugin Refactor (OIDC Implicit Flow)
OpenID with line.biz - email in JWT , missing in userinfo

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 »