Usa Discourse come provider di identità (SSO, DiscourseConnect)

Sono stato in grado di usarlo per creare un sistema di collegamento account per il mio server Minecraft! Ho pensato di condividere come si presenta! Era la prima volta che lavoravo con Discourse SSO, quindi potrei aver complicato eccessivamente tutto. Tuttavia, funziona, che è la cosa principale.

4 Mi Piace

Ciao, ho fatto tutto correttamente. ma quando l’utente non è connesso a Discourse, viene visualizzato un popup di accesso utente. quando compilo nome utente e password, non mi reindirizza all’URL di ritorno. puoi aiutarmi?

Presumo che il nonce sia lì per prevenire replay attack. Ho letto online che i replay attack non sono possibili con HTTPS, che è quello che sto usando. Quindi ho ancora bisogno del nonce? Chiedo perché non sono sicuro di dove memorizzarlo. Ha senso memorizzarlo come cookie sicuro in testo semplice nel browser dell’utente? e poi leggerlo dal browser insieme al payload di ritorno?

Questa libreria, collegata dal post originale GitHub - ArmedGuy/discourse_sso_node: npm package for Discourse SSO login features. non utilizza il nonce durante la validazione dell’utente.

Sì, devi ancora convalidare il nonce perché impedisce il riutilizzo dei payload che Discourse invia quando reindirizza gli utenti al tuo sito.

Ad esempio, supponiamo che il tuo sito abbia dei contenuti dietro un paywall a cui possono accedere solo i membri del gruppo subscribers su Discourse e utilizzi il campo groups nel payload che Discourse invia al tuo sito per visualizzare i contenuti a pagamento solo ai membri del gruppo subscribers. Se non convalidi il nonce, un utente che non fa più parte degli subscribers potrebbe utilizzare un vecchio payload di quando era membro per accedere al tuo sito e visualizzare i contenuti a pagamento.

È meglio memorizzare il nonce in un database con una breve data di scadenza ed eliminare il nonce dal database non appena viene utilizzato. Tuttavia, se non puoi utilizzare un database, puoi utilizzare un cookie per memorizzare il nonce, ma devi eseguire alcuni passaggi aggiuntivi per prevenire il riutilizzo del payload:

  1. allega una data di scadenza al nonce quando lo generi, ad esempio 10 minuti dal momento attuale
  2. firma l’intero cookie (nonce + data di scadenza) per impedire agli utenti di modificare il nonce e/o la data di scadenza
  3. verifica la firma del cookie e assicurati che il nonce non sia scaduto

Ciò dovrebbe fornirti una protezione sufficiente contro il riutilizzo del payload. Tieni presente che tecnicamente rimane possibile riutilizzare un payload, ma sarà limitato a una finestra di 10 minuti invece che per sempre.

Una soluzione più semplice che non richiede un cookie è includere la data di scadenza in un campo personalizzato nel payload che generi. Quindi, quando Discourse reindirizza gli utenti al tuo sito con un payload, i tuoi campi personalizzati verranno inclusi e potrai recuperare la data di scadenza e verificare che non sia scaduta. Per includere un campo personalizzato nel payload, devi includere un campo con prefisso custom., quindi il tuo payload apparirà così:

nonce=NONCE&return_sso_url=RETURN_URL&custom.expiration_date=TIMESTAMP
4 Mi Piace

Potresti anche memorizzare il nonce nella sessione, che impedirà anche all’utente di manometterlo.

3 Mi Piace

Tornando su questo thread anni dopo

Qualcuno può dirmi (@pfaffman o @tobiaseigen o @iamntz) cosa restituisce il provider SSO di Discourse? So che posso “provarci e vedere”, ma sarebbe bello averlo documentato. Il codice di esempio PHP di GitHub non menziona nemmeno altri campi.

Idealmente, invierebbe gli stessi campi di quando Discourse utilizza lo script esterno per SSO, come ID esterno, email, nome utente, nome, foto avatar, ecc. In modo da poter importare questi dati e creare un utente dalla nostra parte!

Dice anche a WordPress l’email?

E i gruppi, i badge, ecc.? Possiamo trovare queste informazioni effettuando chiamate REST?

Infine, per quanto riguarda i messaggi privati dell’utente e altre cose? Immagino che se Discord fosse un provider oAuth e permettesse alle nostre app di consumare queste cose, sarebbe fantastico.

Quando tento abilitare Discourse Connect ottengo questo errore:
enable_discourse_connect: Non puoi abilitare DiscourseConnect e l'invito solo allo stesso tempo.

Qualche idea?

Vedo che hai posto la stessa domanda qui: Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso) - #537. Se stai cercando di configurare l’impostazione enable discourse connect e non l’impostazione enable discourse connect provider, l’altro argomento è il posto giusto per porre la tua domanda.

L’impostazione enable discourse connect provider serve quando vuoi usare il tuo sito Discourse come provider di identità per un altro sito. L’impostazione enable discourse connect serve quando vuoi accedere agli utenti a Discourse tramite un sito esterno.

1 Mi Piace

Ho implementato la procedura in Python per un’applicazione Flask che sto costruendo. Ecco del codice boilerplate per chiunque ne abbia bisogno. I passaggi delineati in questo argomento sono stati abbastanza semplici da seguire, ma non sono uno specialista della sicurezza, quindi se ho trascurato qualcosa, per favore fatemelo sapere!

https://gist.github.com/ScottMastro/011b7a823177ae9022aac35cee

2 Mi Piace

Stiamo cercando di implementare Discourse come provider SSO e quello che non capiamo è come Discourse fa a sapere quale utente deve essere verificato? Le istruzioni dicono: “Crea un nuovo payload con nonce e url di ritorno”. Ma quando lo invii tramite fetch a Discourse, come fa Discourse a sapere quale utente controllare per vedere se è loggato? Scusa se questa sembra una domanda stupida, ma non riesco a capire come funzioni e ho lavorato con molti sistemi di autenticazione nel corso degli anni, quindi ho una certa familiarità. L’email dell’utente per cui stiamo cercando di verificare lo stato di accesso deve essere inclusa nel payload inviato a Discourse? Se sì, qual è la struttura esatta del payload che deve essere inviato a Discourse? Se no, di nuovo, cosa sta controllando esattamente Discourse? La mia ipotesi è che chiediamo all’utente la sua email da parte nostra, e poi inviamo il payload con l’email a Discourse per vedere se quell’utente particolare è loggato, ma non è quello che dicono le istruzioni, quindi sono totalmente confuso. Grazie per qualsiasi aiuto.

Non importa. Abbiamo risolto. Pensavamo che l’URL SSO dovesse essere inviato come richiesta POST all’istanza Discourse e poi ricevere una risposta. Ora vediamo che si tratta di un reindirizzamento a Discourse, e poi Discourse reindirizza nuovamente al nostro sito. Quindi ora è chiaro cosa fare. Scusate per il post precedente.

3 Mi Piace

FYI/FWIW: Ho inviato una PR per consentire un parametro prompt=none nella richiesta di autenticazione. Simile a una funzionalità nel protocollo OpenID Connect, questo consente a un consumer SSO di verificare se un utente/client è già connesso, senza inviarlo a una finestra di dialogo di accesso se non lo è.

La PR è in attesa di una revisione finale da parte di qualcuno del team Discourse da circa 8 settimane; sembra un tempo piuttosto lungo di quanto mi aspetterei. :crying_cat_face:

7 Mi Piace

Ciao @mdoggydog - scusa per il lunghissimo ritardo!\n\nHo appena rivisto e unito la PR - grazie per il contributo! :raised_hands:

3 Mi Piace

Evvai! Grazie, @david.

Come promesso, ho appena aggiornato l’articolo della wiki qui per includere una descrizione del nuovo parametro (e del precedente nuovo parametro logout, e per correggere alcuni piccoli refusi/errori grammaticali, e per aggiungere una sezione di riferimenti che documenta il payload sso= come lo capisco dopo aver esaminato il codice sorgente).

2 Mi Piace

Voglio smettere di usare il nostro sito web come SSO per Discourse e invece utilizzare gli strumenti di accesso integrati di Discourse per limitare l’accesso a determinati materiali sul nostro sito web.

Penso che lo strumento giusto da usare sia: GitHub - discourse/discourse-auth-proxy: An http proxy that uses the DiscourseConnect protocol to authenticate users

Non ho trovato istruzioni dettagliate su come usarlo.

Posso installarlo nello stesso droplet DigitalOcean del nostro sito Discourse o devo ospitarlo altrove?

Modifica: ho messo in grassetto la mia domanda :slight_smile:

1 Mi Piace

Qualsiasi aiuto sulla domanda sopra? Use Discourse as an identity provider (SSO, DiscourseConnect) - #148 by alehandrof

Sto impostando return_sso_url su un URL che a sua volta ha un parametro di query:

http://localhost:7000/completeLogin?returnto=%2F

Il payload che invio a /session/sso_provider come parametro sso è questo prima della codifica base64:

nonce=ENIwf0bElViDu325dTd6&return_sso_url=http://localhost:7000/completeLogin?returnto=%2F

L’URL a cui Discourse reindirizza effettivamente dopo l’autenticazione è questo (con i parametri sso e sig abbreviati):

http://localhost:7000/completeLogin?returnto=/\u0026sso=...\u0026sig=...

Ciò che mi sorprende qui è che la stringa di query che ho impostato per return_sso_url sembra essere stata decodificata dall’URL da qualcosa, perché ha returnto=/ invece di returnto=%2F. Anche il valore di return_sso_url che trovo all’interno di sso dopo averlo decodificato da base64 ha una barra invece di %2F.

È quello che dovrei aspettarmi che accada? (Se sì, perché?) È un bug in Discourse?

Qual è il motivo per cui il payload sso contiene avatar_url invece di avatar_template come restituito in /u/{username}.json e /session/current.json?

avatar_url non è presente per gli utenti che non hanno impostato un avatar, mentre avatar_template contiene il percorso leter_avatar_proxy effettivamente utilizzato in Discourse per mostrare gli avatar per tali utenti, e avatar_url punta all’immagine avatar originale invece che a una ridimensionata alla dimensione desiderata per gli utenti che hanno impostato un avatar.

Mi sembra che avatar_template sia ciò che chiunque intenda utilizzare le informazioni sull’avatar contenute in sso vorrà—ma che poi dovrà effettuare una richiesta API aggiuntiva per ottenerlo.

2 Mi Piace

Al momento sto implementando l’SSO nella mia app, il login funziona molto bene finora, il logout no.

La mia istanza di Discourse sta reindirizzando correttamente all’URL di ritorno senza alcun parametro sso o sig, ma quando apro Discourse, il mio account è ancora connesso.

Qualche idea?

Presumo che tu stia utilizzando l’impostazione del sito logout redirect di Discourse per reindirizzare gli utenti alla tua app dopo che hanno effettuato il logout da Discourse.
Una possibile causa del problema potrebbe essere se l’impostazione login required è abilitata sul tuo sito Discourse. Quando tale impostazione è abilitata, Discourse reindirizzerà automaticamente gli utenti non autenticati al sito del provider SSO se hanno visitato direttamente il sito Discourse. Ciò significa che a meno che tu non disconnetta gli utenti dalla tua app quando vengono inizialmente reindirizzati all’URL logout redirect, verranno automaticamente connessi a Discourse la prossima volta che visiteranno il sito. Puoi confermare questo comportamento procedendo attraverso il processo con l’ispettore del tuo browser aperto sulla scheda di rete.

Nel caso fosse utile, ecco come il plugin WP Discourse gestisce il reindirizzamento di logout di Discourse: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub.

2 Mi Piace