Allora vuoi usare Discourse come fornitore di identità per la tua web app? Ottimo! Iniziamo.
Abilita l’impostazione del provider DiscourseConnect
Nelle impostazioni del sito di amministrazione di Discourse (/admin/site_settings) abilita l’impostazione enable discourse connect provider e aggiungi una stringa segreta a discourse connect provider secrets (utilizzata per l’hashing dei payload SSO).
Implementa DiscourseConnect nella tua web app:
-
Genera un
noncecasuale: https://en.wikipedia.org/wiki/Cryptographic_nonce. Chiamiamo questo valoreNONCE. Salvalo temporaneamente in modo da poterlo verificare con il valore nonce che verrà restituito nella risposta. -
Crea un nuovo payload con il
NONCEe unRETURN_URL(dove Discourse reindirizzerà l’utente dopo la verifica). Il payload dovrebbe apparire come:nonce=NONCE&return_sso_url=RETURN_URL. L’host diRETURN_URLdeve corrispondere al pattern di dominio utilizzato quando si configurano idiscourse connect provider secrets. -
Codifica in Base64 il payload grezzo sopra. Chiamiamo questo payload
BASE64_PAYLOAD -
Codifica in URL il
BASE64_PAYLOADsopra. Chiamiamo questo payloadURL_ENCODED_PAYLOAD -
Genera una firma HMAC-SHA256 da
BASE64_PAYLOADusando il tuo segreto del provider sso come chiave, quindi crea una stringa esadecimale in minuscolo da questa. Chiamiamo questa firmaHEX_SIGNATURE
Invia la richiesta di autenticazione a Discourse
Reindirizza l’utente a DISCOURSE_ROOT_URL/session/sso_provider?sso=URL_ENCODED_PAYLOAD&sig=HEX_SIGNATURE
Ottieni la risposta da Discourse:
Se i passaggi precedenti sono stati eseguiti correttamente, Discourse reindirizzerà l’utente che ha effettuato l’accesso all’indirizzo RETURN_URL fornito. Riceverai parametri della stringa di query con sig e sso insieme ad alcune informazioni sull’utente. Ora segui i passaggi seguenti:
-
Calcola l’HMAC-SHA256 di
ssousando il segreto del provider sso come chiave. -
Converti
sigdalla sua rappresentazione in stringa esadecimale di nuovo in byte. -
Assicurati che i due valori precedenti siano uguali.
-
Decodifica in Base64
sso; otterrai la stringa di query incorporata passata. Questa avrà una chiave chiamatanonceil cui valore dovrebbe corrispondere al nonce passato originariamente. Assicurati che questo sia il caso e ricordati di eliminare il nonce dal tuo sistema. -
Scoprirai che questa stringa di query conterrà anche una serie di informazioni sull’utente. Usale come ritieni opportuno.
Questo è tutto. A questo punto dovresti aver configurato la tua web app per usare Discourse come provider SSO!
Più parametri, più opzioni
Oltre a nonce e return_sso_url, il payload della richiesta ha diversi parametri opzionali aggiuntivi.
-
prompt: Seprompt=none, la richiesta SSO viene trattata come una richiesta di “semplice verifica”. Se il browser/dispositivo è già connesso a Discourse, Discourse restituirà una risposta SSO di successo che riporta le informazioni di autenticazione dell’utente, come di consueto. Se il browser/dispositivo non è già connesso, Discourse non chiederà all’utente di accedere ed restituirà immediatamente una risposta SSO che riporta il parametrofailed=trueinvece delle informazioni sull’utente. Questo fornisce un meccanismo per interrogare se l’utente è connesso, senza mai reindirizzare l’utente a una finestra di dialogo di accesso se non lo è. -
logout: Selogout=true, la richiesta SSO diventa una richiesta di disconnessione. Se un utente è connesso a Discourse su quel browser/dispositivo, verrà disconnesso da quel dispositivo. In entrambi i casi, Discourse reindirizzerà immediatamente areturn_sso_url, senzassoosigaggiunti alla stringa di query. -
require_2fa: Serequire_2fa=true, Discourse richiederà all’utente di verificare l’autenticazione a due fattori prima di essere reindirizzato indietro. Il payload di risposta includeràconfirmed_2fa=truese l’utente ha completato con successo la verifica 2FA, oppureno_2fa_methods=truese l’utente non ha metodi 2FA configurati.
prompt=none e logout=true sono mutualmente esclusivi; non ha senso fornire entrambi nella stessa richiesta.
Riferimento al payload sso=
Parametri della richiesta:
nonce: (stringa, obbligatorio) una stringa casuale generata in modo sicuroreturn_sso_url: (stringa, obbligatorio) l’URL a cui reindirizzare con la rispostaprompt: (stringa, opzionale) Senone, verifica lo stato di autenticazione senza chiedere all’utente di accedere.logout: (booleano, predefinitofalse) Setrue, disconnette l’utente da Discourse.require_2fa: (booleano, predefinitofalse) Setrue, richiede all’utente di verificare l’autenticazione a due fattori prima di essere reindirizzato indietro.
Parametri del risultato:
-
Non c’è payload
sso=o firma in risposta a una richiesta di logout, solo un reindirizzamento al semplicereturn_sso_urldella richiesta. -
Il payload del risultato per una richiesta di accesso conterrà sempre il
nonce, riflesso dalla richiesta. -
Il payload del risultato rifletterà anche qualsiasi altro parametro di richiesta. Non fare affidamento su questo comportamento; non è necessariamente intenzionale e non è un aspetto garantito dell’API. (Ad esempio, perché il parametro
return_sso_urlviene copiato nel payload inviato areturn_sso_url?) -
Se la richiesta non è riuscita ad autenticare un utente, il payload del risultato conterrà
failed=true. -
Se la richiesta è riuscita ad autenticare un utente, il payload del risultato conterrà le credenziali/informazioni dell’utente:
external_id: (stringa) ID utente di Discourseusername: (stringa) nome utente/handlename: (stringa) nome reale dell’utenteemail: (stringa) indirizzo emailavatar_url: (stringa) URL CDN completo dell’immagine avatar caricata dall’utenteadmin: (booleano)truese l’utente è un amministratore, altrimentifalsemoderator: (booleano)truese l’utente è un moderatore, altrimentifalsegroups: (stringa) elenco di gruppi (per nome) separati da virgole a cui appartiene l’utenteprofile_background_url: (stringa) URL CDN completo dell’immagine di sfondo del profilo dell’utentecard_background_url: (stringa) URL CDN completo dell’immagine di sfondo della tessera dell’utenteconfirmed_2fa: (booleano)truese l’utente ha completato la verifica 2FA (presente solo quando è stato richiestorequire_2fa=true)no_2fa_methods: (booleano)truese l’utente non ha metodi 2FA configurati (presente solo quando è stato richiestorequire_2fa=true)
name,avatar_url,profile_background_urlecard_background_urlpotrebbero essere assenti se l’utente non li ha impostati. (Qualsiasi elemento con un valorenilall’interno di Discourse sarà omesso dalla risposta.)
Implementazioni ufficiali di Discourse su “Utilizzo di Discourse come fornitore di identità”:
- Un proxy http (usando golang) che utilizza Discourse SSO per autenticare gli utenti (solo amministratori): GitHub - discourse/discourse-auth-proxy: An http proxy that uses the DiscourseConnect protocol to authenticate users · GitHub (realizzato da @sam)
Implementazioni contribuite dalla community su “Utilizzo di Discourse come provider SSO”:
-
Uno script PHP che implementa Discourse come provider SSO: Discourse sso provider login · GitHub (realizzato da @paxmanchris)
-
Erlang:
https://github.com/reverendpaco/discourse-as-sso-erlang -
Node.js:
GitHub - edhemphill/passport-discourse: A Passport strategy for authenticating using a Discourse forum · GitHub
GitHub - ArmedGuy/discourse_sso_node: npm package for Discourse SSO login features. · GitHub -
ASP.NET Core (richiede solo configurazione):
GitHub - Biarity/DiscourseSso: Easy, configurable Discourse SSO: GET /auth/login -> recieve a JWT with user data · GitHub -
Estensione MediaWiki (PHP):
DiscourseSsoConsumer, a SSO extension for MediaWiki (realizzato da @mdoggydog)
