Ciao! Abbiamo sviluppato un plugin SSO personalizzato per raggruppare le credenziali di accesso della nostra azienda in un pacchetto utilizzabile da Discourse per gestire gli accessi e la creazione degli account. Con la versione v2.7.0beta4, abbiamo iniziato a ricevere errori relativi alla mancata fornitura di un nuovo parametro: secure_session. Non riesco a trovare alcuna informazione sul formato che questo parametro dovrebbe avere o sul suo contenuto. Esiste una documentazione aggiuntiva per questo aggiornamento?
Sai qual è il messaggio di errore esatto che stai visualizzando? La mia comprensione è che Discourse ora lega il parametro nonce dell’SSO alla sessione dell’utente. Ciò significa che se un’app sta generando il nonce effettuando una richiesta in background a /session/sso, il nonce non sarà valido. È possibile che questo sia il problema che stai riscontrando.
Il file service_gateway_current_user.rb fa parte del nostro plugin per costruire il payload da inviare a DiscourseSingleSignOn in base alle intestazioni “Service Gateway” (“Service Gateway” è la nostra struttura interna aziendale per determinare se l’utente è loggato nel nostro sistema).
Per spiegare quella parte dello stack:
La nostra funzione current_user utilizza le intestazioni per cercare un SingleSignOnRecord in cui external_id corrisponde all’ID utente nelle intestazioni. Se non è così, passiamo alla sezione create_sso_record.
create_sso_record crea un hash – { external_id: sg_headers[:user_id], email: sg_headers[:email] } – e lo invia alla nostra funzione upsert_sso_record.
upsert_sso_record prende quell’hash (payload nel contesto sottostante) e tenta di creare un oggetto DiscourseSingleSignOn:
def upsert_sso_record(payload)
encoded_query = Base64.encode64(payload.to_query)
sig = OpenSSL::HMAC.hexdigest('sha256', ENV['SSO_SECRET'], encoded_query)
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query)
if SiteSetting.verbose_sso_logging
Rails.logger.warn("Verbose SSO log: Started SSO process\n\n#{sso.diagnostics}")
Rails.logger.warn("SSO Payload:\n\n#{payload}")
end
begin
user = sso.lookup_or_create_user(@request.ip)
rescue ActiveRecord::RecordInvalid => ex
Rails.logger.error "Unable to find/create sso user #{ex}"
end
user
end
La chiamata a parse sulla terza riga di quella funzione è dove sembra manifestarsi il problema. Non appena tenta di initialize l’oggetto, il valore secure_session che si aspetta non è presente.
Mi chiedo se impostare la nuova impostazione del sito discourse_connect_csrf_protection su false possa risolvere il problema per te. Questa impostazione del sito è nascosta, quindi deve essere configurata dalla console di Rails. Puoi trovare dettagli al riguardo nelle risposte a questo argomento: DiscourseConnect flow no longer functions.
Purtroppo, non credo che questa nuova impostazione sia sufficiente da sola: gli interni del codice richiederanno comunque il passaggio di un oggetto secure_session, anche se non viene utilizzato.
In generale, consigliamo di utilizzare gli hook ufficiali per i plugin di autenticazione, invece di sovrascrivere l’implementazione di DiscourseConnect del core.
È difficile essere certi senza vedere l’intero plugin, ma potresti provare a passare un valore nil per secure_session. Fare questo, insieme all’attivazione della nuova impostazione del sito, potrebbe aiutare a far funzionare le cose un po’ meglio.
Dopo aver analizzato ulteriormente il codice di v2.7.0.beta4, vedo che ApplicationController ha una definizione secure_session. Modificare il nostro codice del plugin come segue sembra funzionare nel nostro ambiente di Staging:
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query, secure_session: secure_session)