Hi , I wrote this SimpleSAMLphp authentication module to be able to use Discourse as an SSO provider within a SimpleSAMLphp installation. I.e. you can use Discourse as an SSO provider for any services that supports SAML or Shibboleth authentication, which is really nice.
Let me know what you think (if interested to comment on the code you can use Github Issues).
That’s great! If you’d like to make the module more visible, you could create a topic about it in our extras category. That category is a directory of all extensions & integrations for Discourse which are not Discourse plugins,
I’m implementing this SSO on an existing web site and I just want to check how people are “presenting” their login method to users.
For example, let’s say my web site at www.example.com has a Login button in the top nav.
Should that login button instantly take people to my discourse login auth page? Or is it preferable to display a page / modal of information first, something like:
I’m just wondering if people will get confused if they’re not told what’s about to happen?
Does anyone have any user experiences or best practices to share?
And thanks too by the way to @techAPJ for the very detailed first post in this thread, I was able to successfully build this in to my ASP.NET web site from scratch following your steps
Is it possible to include a state parameter that gets returned unchanged, like as is done in OAuth? Asp.net core authentication middleware depends on generating a correlation id to prevent CSRF attacks, and I don’t currently have an easy way to include this.
@jessicah I tried this today and yes, it works fine.
' Create a Return URL
Dim strReturnURL As String = "https://www.example.com/authtestRETURNURL.aspx?myownparametershere=surewhynot"
' Generate a random nonce. Save it temporarily so that you can verify it with returned nonce value
Dim strNonce As String = Guid.NewGuid().ToString("N")
' Create a new payload with nonce and return url (where the Discourse will redirect user after verification)
' Payload should look like: nonce=NONCE&return_sso_url=RETURN_URL
Dim strPayload As String = "nonce=" & strNonce & "&return_sso_url=" & strReturnURL
Then on the page which is called back you’ll find this inside your decoded SSO query string:
Multi-site approaches to using discourse-auth-proxy?
Are there any examples or recommendations for using Discourse as SSO provider for multi-site authentication?
It seems like the there are two basic multisite approaches:
Use multiple instances of discourse-auth-proxy, one per site protected.
Use a single instance of discourse-auth-proxy so the payload containing return_sso_url changes based upon the source of the login request.
I think either of these could work, but the issue with these two approaches, is
that you still require logging into each different site.
There is also the risk that something is stored in Postgres that will get overwritten by each login from the different sites. ie: site1.com. site2.com
(I don’t know the details of Discourse auth/PG schema, so I don’t know)
What would be ideal is a way to have login performed once, which gets you logged into all the sites in the multi-site group. ie, site1.com, site2.com, site3.com
Apparently Stackoverflow does this using a combination of localSession storage and Iframes as the main enabler. tech description
But I’d really love to know if someone has implemented any approach to
multisite login using Discourse as the SSO provider.
approach 1: multiple instances of discourse-auth-proxy
approach 2: hacked discourse-auth-proxy affecting return_sso_url in payload.
approach 3: #1 or #2 implemented such that logging in once, means you do not have to login again when moving from site1.com to site2.com
I am tagging you @sam, since you originally authored the Go discourse-auth-proxy program.
The problem is that the return to url will be handle by the urldecode function in PHP(it’s the core workflow in MediaWiki Authentication), and the wpLoginToken value will be unexpected change from 123+\ to 123 \.
Since the provider and the non-provider settings are for opposite use cases—using Discourse to manage users for something else versus using something else to manage users for Discourse—displaying these settings mixed together invites misconfiguration. It would be less confusing if the two provider settings were consecutive and either entirely before or entirely after the non-provider settings.
@techAPJ Can this be used with AWS Cognito? I want to create an app in AWS Amplify for my discourse community and want my app to be authenticated through discourse.
@mdoggydog Merci pour la récente mise à jour de l’extension MediaWiki DiscourseSsoConsumer. Nous nous demandions quoi faire concernant les utilisateurs qui étaient déconnectés de notre wiki sans s’être déconnectés de Discourse, et $wgPluggableAuth_EnableAutoLogin n’était certainement pas ce que nous voulions, car cela empêche l’accès anonyme au wiki. Le paramètre $wgDiscourseSsoConsumer_AutoRelogin que vous avez ajouté est exactement ce dont nous avions besoin.
J’essaie d’utiliser l’exemple PHP du post original, mais la façon dont ils stockent les choses n’a pas de sens. Ils stockent simplement des valeurs dans une base de données SQL avec les clés login et nonce. Si je veux utiliser SQL pour stocker les nonces, à quoi ressemblerait exactement ma base de données SQL ?
Quelques autres informations qui pourraient aider sont à quoi je destine ceci : j’espère lier un utilisateur Discourse à un compte Minecraft en générant un lien SSO lié à leur UUID. Après une connexion réussie avec Discourse, je vais stocker leur UUID et leur ID Discourse dans une table.
Jusqu’à présent, j’ai réussi à faire fonctionner l’exemple PHP, mais je ne comprends pas bien comment je devrais le modifier pour qu’il fonctionne pour mon cas d’utilisation. Idéalement, je veux générer le lien via une requête GET et l’envoyer à l’utilisateur, de sorte que l’UUID soit déjà associé au nonce.
Merci pour ce post, car je serais encore plus perdu sans lui !
Edit : Pour les nonces, ne serait-il pas préférable de stocker les nonces dans la table et de rechercher par celle-ci ? Je sais que je dois faire correspondre le nonce, mais à moins de pouvoir passer des informations supplémentaires dans l’URL de redirection (ce que je n’ai pas réussi à faire), je ne suis pas sûr de la façon de référencer correctement le nonce.
J’ai supprimé une partie de la valeur du paramètre sso que vous aviez fournie. À moins que quelqu’un ne connaisse votre clé secrète, il ne serait pas en mesure de décoder la valeur, mais il semblait tout de même plus sûr de ne pas fournir la valeur complète. Cela n’aura aucun rapport avec l’erreur 502 que vous rencontrez.
Il semble s’agir d’une erreur de base de données. En effet, j’ai essayé le même plugin et la même configuration sur un autre site web Discourse, et cela fonctionne. Comment puis-je résoudre ce problème ?
Il semble que tenter de s’authentifier dans discourse-auth-proxy avec des noms d’utilisateur ou des noms de groupe non-ASCII (chinois dans mon cas) entraîne une erreur car les cookies ne peuvent pas contenir ces caractères. Voici ma correction : (avertissement : je ne suis pas vraiment familier avec golang)
diff --git a/main.go b/main.go
index 1b1dc28..18f8c9e 100644
--- a/main.go
+++ b/main.go
@@ -154,7 +154,12 @@ func redirectIfNoCookie(handler http.Handler, r *http.Request, w http.ResponseWr
var username, groups string
if err == nil && cookie != nil {
- username, groups, err = parseCookie(cookie.Value, config.CookieSecret)
+ var value string
+ value, err = url.QueryUnescape(cookie.Value)
+ if err != nil {
+ return
+ }
+ username, groups, err = parseCookie(value, config.CookieSecret)
}
if err == nil {
@@ -224,7 +229,7 @@ func redirectIfNoCookie(handler http.Handler, r *http.Request, w http.ResponseWr
cookieData := strings.Join([]string{username, strings.Join(groups, "|")}, ",")
http.SetCookie(w, &http.Cookie{
Name: cookieName,
- Value: signCookie(cookieData, config.CookieSecret),
+ Value: url.QueryEscape(signCookie(cookieData, config.CookieSecret)),
Expires: expiration,
HttpOnly: true,
Path: "/",
Merci de votre signalement ! Pourriez-vous créer une Pull Request (PR) sur le dépôt GitHub afin que nous puissions intégrer ce changement dans la version officielle ?