Discourse OpenID Connect (OIDC)

:discourse2: Riepilogo Discourse OpenID Connect consente di utilizzare un provider OpenID Connect come provider di autenticazione per Discourse.
:open_book: Guida all’installazione Questo plugin è incluso nel core di Discourse. Non è necessario installarlo separatamente.

Funzionalità

Il plugin mira a fornire un’implementazione minimale di la specifica. Nello specifico, supporta il “Flusso del codice di autorizzazione”. Per iniziare, segui le istruzioni per l’installazione del plugin o contatta il tuo provider di hosting.

Il nostro plugin oauth2-basic può essere utilizzato per connettersi ad alcuni provider openid-connect (OpenID Connect si basa su OAuth2). Tuttavia, questo plugin richiede molta meno configurazione manuale e può utilizzare il “ID Token” JWT se un’API JSON non è disponibile.

La configurazione viene eseguita automaticamente utilizzando un Documento di scoperta OpenID Connect. Secondo la specifica, questo dovrebbe trovarsi in <dominio_emittente>/.well-known/openid-configuration, ma Discourse supporta qualsiasi percorso per consentire implementazioni non conformi (ad esempio Azure B2C). Il documento di scoperta viene memorizzato nella cache per 10 minuti, per migliorare le prestazioni sui siti ad alto traffico.

Se il documento di scoperta include un parametro userinfo_endpoint, il plugin lo utilizzerà per raccogliere i metadati dell’utente. In caso contrario, il plugin estrarrà i metadati dal id_token (un JWT) fornito dall’endpoint del token. Il plugin NON verifica l’autenticità della firma JWT, poiché ciò aumenterebbe significativamente la complessità. Questa decisione è supportata da la specifica:

Se il ID Token viene ricevuto tramite comunicazione diretta tra il Client e l’Endpoint del Token (come avviene in questo flusso), la convalida del server TLS PUÒ essere utilizzata per convalidare l’emittente al posto della verifica della firma del token.

Per i provider di identità che supportano l’autorizzazione senza segreto utilizzando il “Flusso del codice di autorizzazione con chiave di prova per lo scambio di codici”, PKCE dovrebbe essere abilitato e la configurazione client_secret può essere omessa.

Configurazione

Opzioni di configurazione di base

  • openid_connect_enabled: Abilita l’autenticazione OpenID Connect

  • openid_connect_discovery_document: URL del documento di scoperta OpenID Connect. Normalmente situato in https://tuo.dominio/.well-known/openid-configuration

  • openid_connect_client_id: ID client OpenID Connect

  • openid_connect_client_secret: Segreto client OpenID Connect

  • openid connect rp initiated logout: Reindirizza l’utente all’endpoint end_session_endpoint dopo il logout. Deve essere supportato dal tuo provider di identità e incluso nel documento di scoperta.

  • openid connect rp initiated logout redirect: (opzionale) Il post_logout_redirect_uri che verrà passato all’endpoint di logout. Se fornito, deve essere registrato presso il provider di identità.

  • openid_connect_authorize_scope: Gli ambiti (scopes) inviati all’endpoint di autorizzazione. Questo deve includere ‘openid’

  • openid_connect_use_pkce: Abilita la Chiave di Prova per lo Scambio di Codici (PKCE) per l’autenticazione OpenID Connect.

  • openid_connect_verbose_logging: Registra informazioni dettagliate sull’autenticazione openid-connect in /logs. Tieni questa opzione disabilitata durante l’uso normale.

Opzioni di configurazione avanzate

  • openid_connect_token_scope: Gli ambiti inviati quando si richiede l’endpoint del token. La specifica ufficiale non lo richiede.

  • openid_connect_error_redirects: Se il motivo dell’errore della callback contiene il primo parametro, l’utente verrà reindirizzato all’URL nel secondo parametro. Utilizzato per implementazioni insolite che inviano errori in risposta all’input dell’utente (ad esempio Azure B2C)

  • openid_connect_allow_association_change: Consenti agli utenti di disconnettere e riconnettere i propri account Discourse dal provider OpenID Connect

  • openid_connect_groups_claim: Il nome della clausola (claim) nella risposta OIDC[1] che contiene i gruppi dell’utente come un array di stringhe. Lascia vuoto per disabilitare la sincronizzazione dei gruppi. Vedi Sincronizzazione dei gruppi di seguito.

  • openid_connect_user_field_mappings: Mappature delle clausole OIDC[2] che verranno memorizzate nei Campi Utente di Discourse. I campi utente sono identificati dal loro ID numerico, che può essere trovato nell’URL quando li modifichi tramite il pannello di amministrazione.

Sincronizzazione dei gruppi

Il plugin può sincronizzare automaticamente le appartenenze ai gruppi dal tuo provider OpenID Connect ai gruppi di Discourse. Ad ogni accesso, il plugin leggerà la clausola configurata dal token OIDC e aggiornerà di conseguenza le appartenenze ai gruppi dell’utente. Per abilitare la sincronizzazione dei gruppi:

  1. Configura il tuo provider di identità per restituire un array di gruppi in una delle clausole. Questo deve essere un array di stringhe.

  2. Imposta openid_connect_groups_claim sul nome della clausola nel token OIDC che contiene i gruppi dell’utente (ad esempio cognito:groups). Una volta impostato, inizierà a sincronizzare le informazioni con il sistema “Gruppi Associati” di Discourse.

  3. Trova il Gruppo Discourse che desideri collegare. Vai su “Impostazioni” → “Membri” → “Automatico” e scegli i Gruppi Associati da collegare. Questo elenco a discesa viene popolato con le informazioni dal provider di identità, quindi almeno un membro del gruppo deve aver effettuato l’accesso affinché appaia un’opzione.

Esempio di configurazione

Qui configureremo il plugin openid-connect per connettersi al provider OpenID Connect di Google. Questo replica una funzionalità già esistente nel core di Discourse, ma funge da esempio accessibile.

  1. Vai su OpenID Connect  |  Sign in with Google  |  Google for Developers e segui le istruzioni per ottenere le credenziali OAuth.

  2. Nella stessa pagina, segui le istruzioni per aggiungere un URI di reindirizzamento. Questo dovrebbe essere https://<tuo_forum>/auth/oidc/callback (senza una barra finale)

  3. Vai alle impostazioni del tuo sito Discourse e cerca “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 (con uno spazio in mezzo)

  4. Fatto. Il pulsante “Accedi con OpenID Connect” ora effettuerà l’accesso utilizzando Google :tada:. Questi stessi passaggi possono essere applicati ad altri provider con modifiche minime.

Debugging

Oltre all’impostazione verbose_logging descritta sopra, puoi accedere ai dati sulle associazioni OIDC utilizzando il plugin data-explorer:

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

O sulla console rails:

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

Note specifiche per provider

Sentiti libero di aggiornare questa sezione se trovi stranezze specifiche di un provider relative a questa integrazione:

Entra ID (precedentemente Azure AD)

Aggiungi l’ambito email e assicurati di utilizzare il documento di configurazione dell’endpoint versione 2. Ad esempio

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

I dettagli dell’URL del documento di scoperta si trovano qui: Web sign in with OpenID Connect - Azure AD B2C | Microsoft Learn

Per far funzionare le email:

Yahoo
  1. Vai su https://developer.yahoo.com/apps e crea una nuova app

  2. Inserisci il nome dell’applicazione e imposta il dominio di callback sul dominio del tuo forum (ad esempio meta.discourse.org)

  3. Sotto Autorizzazioni API, scegli Profili: Lettura/Scrittura Pubblica e Privata. Questo è l’unico modo che conosco per ottenere l’indirizzo email dell’utente

  4. Salva l’app

  5. Nelle impostazioni OIDC di Discourse, imposta il documento di scoperta su

    https://login.yahoo.com/.well-known/openid-configuration
    
  6. Inserisci l’ID client e il segreto da Yahoo

  7. Abilita il plugin OIDC

AWS Cognito
  1. Vai su Cognito e seleziona o crea un nuovo pool di utenti.
  2. Definisci un’app in Client app.
  3. Lascia tutto ai valori predefiniti, ma modifica la configurazione dei Flussi di Autenticazione per selezionare solo ALLOW_REFRESH_TOKEN_AUTH.
  4. Vai alle impostazioni del client app e seleziona la nuova app.
  5. Modifica l’URL di callback in https://tuosito.example.com/auth/oidc/callback.
  6. Seleziona solo il flusso di concessione del codice di autorizzazione tra “Flussi OAuth consentiti”.
  7. Seleziona tutti gli ambiti necessari (io li ho tutti selezionati).
Okta
  1. Configura Discourse con l’ID client e il segreto della tua app Okta

  2. Imposta l’URL del documento di scoperta su

    https://{tua-app}.okta.com/.well-known/openid-configuration
    
  3. In Discourse, imposta openid connect authorize scope su openid email

:discourse2: Ospitato da noi? Questo plugin è disponibile nei nostri piani Business e Enterprise. OAuth 2.0 & OpenID Connect Support | Discourse - Civilized Discussion

:spiral_notepad: Devi automatizzare le registrazioni degli utenti? Vedi Auto-provisioning user accounts when SSO is enabled


  1. token o payload userinfo ↩︎

  2. dal token o dal payload userinfo ↩︎

52 Mi Piace
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

Ciao,
stiamo utilizzando il plugin di autenticazione OpenID Connect con un’installazione Discourse su AWS.
Abbiamo distribuito i container Discourse, Discourse Sidekiq e Redis (basati su Bitnami, ma non cacciatemi ;)). Il DB è in esecuzione su AWS RDS. Usiamo KeyCloak.

Le cose funzionano.

Ma a volte, dopo un riavvio dell’attività AWS di Discourse, succede che pensa di avere il documento di discovery nella cache, ma poi non c’è nessun documento lì. E non tenta di recuperarlo nuovamente da 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

Nell’app del browser vedo: Impossibile recuperare la configurazione dall’identity provider. Riprova.

Cosa puoi consigliare?

2 Mi Piace

Ciao,

C’è un modo per impostare la sorgente dell’avatar utente di Discourse su un campo specificato nel servizio openID?

Modifica: stiamo usando keycloak

1 Mi Piace

Ciao,

Ho un requisito simile a quello di @Tomáš_Guba: vorrei ottenere un valore da una voce personalizzata nel profilo utente e utilizzarlo in un campo utente [personalizzato].

Nel mio caso specifico, ho un documento di discovery con un userinfo_endpoint

C’è qualcosa di simile nella roadmap del plugin?

Grazie

1 Mi Piace

Ciao, sono riuscito a far funzionare il plugin con il mio SSO openID ma non viene compilato nel campo nome utente dell’altro sistema o email tra gli altri campi…

Immagino che dovrei configurare qualcosa nel campo “rivendicazioni openid connect”, ma non so come configurare direttamente questo campo. Qualcuno può darmi un esempio? Ecco alcune stampe di come è il mio progetto:
https://imgur.com/gallery/LWvkJUV

1 Mi Piace

C’è un modo per evitare di “perdere” il percorso originale quando si accede a un post privato?

Se visitiamo una pagina privata e clicchiamo su uno dei pulsanti di accesso presenti in quella pagina, quando veniamo reindirizzati al sito, finiamo sulla pagina delle categorie.

Ciao @david,

Puoi per favore dare un’occhiata al problema menzionato nel seguente post? Vorrei usare il plugin OIDC invece di OAuth basic. Ma riscontro lo stesso problema: non riesco a passare parametri alla richiesta /authorize. Ho inserito il valore nel plugin nel formato foo=bar.

Non sono riuscito a farlo funzionare su LinkedIn. Qualcun altro ci è riuscito? Riesco ad accedere a LinkedIn dopo essere stato reindirizzato lì quando clicco sul pulsante “accedi con…” e poi “autorizzo” la mia app a usare la mia email da LinkedIn, poi ricevo “Spiacenti, si è verificato un errore durante l’autorizzazione del tuo account. Riprova.”

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

Ho ancora problemi con questo. Ricevo il seguente errore:

(oidc) Authentication failure! invalid_credentials: OAuth2::Error, invalid_request: A required parameter "client_secret" is missing {"error":"invalid_request","error_description":"A required parameter

È un errore di omniauth e sembra essere correlato [potenzialmente] a questo: No longer works with oauth2 gem v2.0+ · Issue #68 · decioferreira/omniauth-linkedin-oauth2 · GitHub

L’aiuto è apprezzato!

Ricevo i seguenti errori:

(oidc) Authentication failure! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Discovery document is missing

OIDC Log: Fetching discovery document raised error Faraday::ConnectionFailed FinalDestination: lookup failed

Ho impostato il plugin “openid connect discovery document” nelle Impostazioni di amministrazione come: https://<auth_provider>/.well-known/openid-configuration e riesco a raggiungerlo con successo nel container Docker dell’app in esecuzione con un comando Curl e persino nella console Rails.

Hai qualche idea sul motivo per cui ricevo questi errori? Non riesco a integrarmi correttamente a causa di ciò. Inoltre, mi trovo dietro la intranet e utilizzo un proxy aziendale, se questo può essere d’aiuto. Come ho detto, con il proxy abilitato nell’ENV del container, posso raggiungere correttamente l’URL “openid connect discovery document”.

1 Mi Piace

2 post sono stati divisi in un nuovo argomento: Consentire più origini OIDC

Un post è stato diviso in un nuovo argomento: Sovrascrittura degli avatar con OIDC

Ciao!

Nuova domanda: questo plugin gestisce la gestione delle sessioni? (Final: OpenID Connect Session Management 1.0).
Non credo perché anche se l’OP invia i dati session_state, non vedo da nessuna parte nel codice dove vengano memorizzati come cookie o altro.

Quindi questa è una domanda/richiesta di funzionalità :slight_smile: Sarebbe fantastico!

2 Mi Piace

Quando si utilizza questo plugin con AWS Cognito, per effettuare il logout, Cognito richiede il passaggio di un parametro client_id all’URL di logout. Per quanto ne so, non c’è modo di aggiungere parametri di query aggiuntivi all’URL di logout, è corretto? Se no, è possibile aggiungere questa funzionalità?

Ehi gente :wave:t3:

Ho scritto una piccola estensione per questo plugin (tecnicamente sotto forma di tema/componente) - per nascondere il pulsante “Accedi tramite OIDC” nel popup di accesso, ma avviare il flusso di accesso tramite OIDC accedendo a un URL speciale.

discourse-autooidc.zip (1,0 KB)

Il caso d’uso per questa funzionalità è fornire un accesso sicuro e conveniente (automatico) tramite oauth ai membri della nostra azienda, senza esporre un link pubblico al provider OAuth (Authentik nel nostro caso, ma dovrebbe funzionare anche con Authelia, Keycloak, Auth0, Okta,…) e senza infastidire tutti gli altri utenti con un pulsante di accesso tramite OIDC che non possono o non dovrebbero mai usare.

Per accedere tramite OIDC, basta chiamare https://<il-tuo-URL-base-di-Discourse>/login#autooidc

3 Mi Piace

Potrebbe interessarti GitHub - discourse/discourse-hide-auth-method: A theme component which allows hiding a specific login method from the UI, without fully disabling it, che fa qualcosa di simile

3 Mi Piace

Keycloak supporta Backchannel logout URL (URL di logout in backchannel):

URL che causerà il logout del client quando viene inviata una richiesta di logout a questo realm (tramite end_session_endpoint). Se omesso, in questo caso non verrà inviata alcuna richiesta di logout al client.

Sarebbe fantastico se questo plugin esponesse un endpoint che accetta un payload da Keycloak ed effettua immediatamente il logout di un utente da tutte le sessioni. Altrimenti, quando disabilitiamo un utente in Keycloak, dobbiamo attendere maximum session age (che per impostazione predefinita è piuttosto elevato).

Potresti anche disconnetterli da tutte le sessioni utilizzando la pagina di amministrazione dell’utente (ad esempio, /admin/-1/system) e fare clic sul pulsante Log Out nella parte superiore della pagina.

Ciao,

Quando il recupero del documento di discovery fallisce (ad esempio in caso di timeout), il plugin memorizza nella cache l’errore, il che significa che l’autenticazione non è disponibile per 10 minuti. È possibile non memorizzare nella cache l’errore in modo che il recupero venga ritentato prima?

Saluti

Mi scuso per il ping, ma c’è una PR aperta per questo che dovrebbe essere banale da unire per aggiungere il supporto PKCE.

@nbianca Ti ho visto essere l’ultimo committer al repository, potresti dare un’occhiata, forse? :folded_hands:

1 Mi Piace