Smoothly integrating Discourse with an existing social site

(Michael Jonathan) #1

Hey all,

I am a developer for a website with social-network like behavior, and we’d like to integrate Discourse into our site. We love how Discourse works and we want to have a Discourse-powered discussion platform on the site. We want to create a seamless experience for users, where Discourse naturally becomes like part of our main site. We maintain our own user database (which should override all user management in Discourse).

We created an instance of Discourse and we attempted to use Discourse SSO. The SSO bit works fine, but the experience is nowhere near seamless. By default the logged-in/out states becomes out-of-sync:

  • If a user logs in on our own site login, they don’t become logged in to Discourse. When they visit our Discourse instance, they’re still logged out. They must click one of Discourse’s sign in buttons, where they’ll get redirected to our SSO handler etc. and then back to Discourse where they’ll finally be in a logged-in state.
  • If a user logs out on either our site or Discourse, they don’t automatically become logged out on the other.

We want to have no user-accessible user management features in Discourse (no login/logout buttons, no change of password/usernames); instead our main site sends all user info to Discourse so that Discourse truly becomes a natural part of the site.

What can we do to achieve this? I’ve been browsing through many posts in meta.discourse but there doesn’t seem to be an elegant solution.

  • We’d love it if login/logout endpoints can all be defined within the Discourse admin settings.
  • One thought is that maybe, every time a user opens our Discourse instance, an SSO-like behavior automatically executes, redirecting the user to our own handlers, securely passing in user info via encrypted URL parameters, and then back to Discourse in the proper logged-in/logged-out state.
  • Alternatively we can pass around info using cookies.
  • Other ideas?

We don’t use ROR for our main site at the moment, in fact we have no previous Ruby experience. We’re looking for a natural built-in solution in Discourse, not requiring us to modify/override the Discourse source code.

Also, regarding the user data passed around during SSO login, we see from Official Single-Sign-On for Discourse (sso) that we can send over their externalID, username, email, etc.; in fact we currently do. How can we also pass in the user’s avatar as a URL (as a path to our CDN file) and have Discourse natively use that value to display that user’s avatar across the site?

We appreciate the help.

How to use SSO to sign users in to main application and Discourse
Sharing authentication between root and subdomain
(Jeff Atwood) #2

Do we have any plans here @sam?

(Adam Capriola) #3

After a successful native login you need to redirect the user to your SSO URL (with a redirect back to the intended destination). You have to change your default handling here.

I don’t believe the single sign off functionality has been implemented in Discourse yet.

(Michael Jonathan) #4

After a successful native login you need to redirect the user to your SSO URL (with a redirect back to the intended destination). You have to change your default handling here.

Hi Adam, thanks for replying - can you explain this a bit more? To clarify our current situation, simple SSO login works OK:

  • if a logged-out person opens our instance of Discourse, and then clicks a login button (within Discourse), it will run the SSO mechanism, redirecting our own login page with payloads etc., and once login is complete will redirect back to Discourse. The user will be logged in successfully on both Discourse and the main site.

  • however, if a logged-out person clicks a login button elsewhere on our site (outside of Discourse), it will go to our login page, skipping the whole SSO mechanism (because to perform Discourse SSO we need the payload generated by Discourse, which we can’t get outside the Discourse environment) - thus the user will be logged in only on the main site.

If we try to enforce redirection to Discourse SSO every time a person logs in to our site, it feels very risky as the whole site login may break if our Discourse-dedicated server ever goes down for instance; not to mention the performance hit happening on every login due to the increased number of redirects.

(Adam Capriola) #5

Your current situation is normal; the redirect I described is a little weird since you’re pinging the user back and forth with redirects, but it’s worked flawlessly for me so far. I don’t know if there is any other way to do it. I don’t think worrying about your Discourse server going down is that big a consideration; the user will still be logged in to the other part of your site (you do the redirect only after their login has been validated). They will be redirected a dead page I guess, but I think the potential for your server to go down is too rare to use as a reason not to do this.

To clarify about the redirect, you will want to send the user to here following your native login and append your return path:

That will then send the user to your sso url.

(Admir Hodzic) #6

Have you considered using gavatar .
When I send my user over SSO dicouce without problems fetch gavatar from public site.
All you need at your site yours avatars replace with one with gavatars

(Kane York) #7

I know that has done some magic with the CurrentUserProvider…

(Faeron Sayn) #8

I’m not getting this, but after one validates the user on their own site, how will sending them to path let discourse know the identity of the user and who discourse needs to log in? There is no information encoded in this URL for discourse to know about the user in anyway. Could you clarify of how the process would actually work if we kind of want to log the user into both servies (seemlessly, at least make it seem seemless to the user)

(Kane York) #9

What sending them to that URL does is starts them off on the same path that they get when they click the Log In button on Discourse, then redirecting them back to return_path when it’s done.

(Dean Peterson) #10

return_path no longer works for returning to external sites. The poster of this issue (external return_path issue) made a plugin to fix the problem. I am still trying to get it to work. Apparently return_path worked previously but they made a recent change and it is expected developers write their own plugin to get the ability back.

(Jeff Atwood) #11

It’s a security issue, sorry – we fixed a vulnerability. You can’t have open redirects.

(Sam Saffron) #12

Yeah the plan was to allow a site setting that whitelists allowed domains for redirect.

@depeters instead of writing a plugin why not submit a PR to core?

(Abai) #13

I have the same issue, my basic Discourse SSO works completely fine, but I want it to work in the way described by the topic initiator. This topic is about 1 year old and probably there is a solution to it already. Can I get updated about it?

(Jeff Willette) #14

If I send my users to forum/session/sso after a successful native login how would I give a redirect back to the initial intended destination? I can’t seem to find this info

(Maisa Lino) #15

Hi everyone,
Could anyone tell me how to configure Keycloak as SSO on Discourse ? I have the same necessity as @mjonathangtv.
I need when an user log in on my site he be able to access Disrcourse without do the login again.

I configured the SSO, but when I try to login I receive the error “failure?message=csrf_detected&strategy=oauth2_basic” with the message on the page: “Sorry, there was an error authorizing your account. Perhaps you did not approve authorization?”