OpenID Connect extension not creating new Discourse users

Edit for future readers: This has been solved. It was a bug with Discourse social logins and fullscreen_login. For those using Keycloak as their SSO provider like me, make sure you:

  1. Set your valid redirect URI to https://yourforum.com/auth/oidc/callback
  2. Set your Root URI to the same thing.
  3. Make sure the client is confidential, not public or bearer-only.
  4. Use the client ID you set in Keycloak as the client ID in Discourse. So if you named the keycloak client discourse, that’s what you’re calling it in Discourse.
  5. In Discourse, make sure you set your OpenID discovery document url to https://<your-keycloak-server>/auth/realms/<your-realm>/.well-known/openid-configuration.
  6. You can find your Client Secret in the Keycloak admin panel for your client under “Credentials.”
  7. Make sure “Enable Authorization” and “Enable Service Accounts” are both enabled in the Keycloak client, and “Enable Consent” is false.
  8. Set your Authorization Scopes in Discourse to openid profile email
  9. You don’t need to worry about Token Scopes.
  10. Disable ALL other login methods in Discourse including local logins if you want it to only use Keycloak. For things like Google, Twitter, etc. logins, you can set those up inside Keycloak.
  11. If all goes well, both the Sign Up and Log In buttons in Discourse should redirect the user to your Keycloak realm to log in. Happy single-signing-on.

Hey there. I’m in the process of moving my community from the Watercolor Games community (whose domain is literally going to expire in a few days at the time of writing this) to the new Bit Phoenix Software forum.

With this move, I’m trying to set up a way for community members to sign in to both Discourse and our MediaWiki instance using a Bit Phoenix Account. The wiki is working perfectly however, Discourse, not so much.

I’m using Keycloak as my identity provider and it’s working fine. I have a discourse client set up in it, and I have Keycloak configured as the openid discovery url in my Discourse. I have all other authentication methods in Discourse completely disabled so the user gets redirected to the Bit Phoenix Account login page, a.k.a Keycloak. That works.

I can also log in to my existing administrative user account through Keycloak and it gets me onto the account I created in Discourse during installation - so I still have full admin access to the forum. Awesome!

But, in testing, I had one of the people who moderates the old forum sign in using THEIR Bit Phoenix Account (knowing they wouldn’t possibly have a Discourse account in the new forum yet) and while they can successfully log in to Keycloak, they do not get logged into Discourse (and don’t receive any errors.)

Things I have tried

Enabling verbose logging in OpenID Connect extension

Shows me the moderator logging in and I can see all their keycloak user info. They are indeed logged in according to the logs.

Looking in the Sessions list in Keycloak for the bitphoenix realm

I can see both my administrative session and the moderator’s user session in the list under discourse. Keycloak sees us both as logged in.

Enabling force_https

No effect whatsoever as I figured.

Enabling/disabling/fiddling with various settings pertaining to invite_only, etc. to control user registration

Only affects Discourse UI. Some settings hide and show the Signup button, some disable reading of posts anonymously, none fix the issue.

The Signup button just takes you to the Keycloak UI anyway.

Desired outcome

  • User goes to wiki or discourse forum
  • they’re not logged in, they can read but can’t post
  • they decide to log in so they click “log in” in the wiki or discourse UI
  • they are prompted for a username and password for their Bit Phoenix account
    • they are given the choice to create a new BP account here
    • on doing that, they are forced to verify their email
  • on success they are redirected back to Discourse
  • if an existing Discourse user can be found, great. Sync their profile and log them in.
  • If not, create the new Discourse user based on their Bit Phoenix account and log them in as if they just signed up for Discourse. This doesn’t happen.

Any help is GREATLY appreciated on this one, even more so than usual. This is pretty time sensitive - I have no idea when the Watercolor Games website is gonna drop off the face of the earth suddenly and I wanna have all this stuff set up right then and there so the roll-out is nice and easy. Thanks so much in advance! :slight_smile:

8 Likes

I recommend contacting Jay at https://literatecomputing.com if you need hands on help, his rates are very reasonable.

3 Likes

It’s not really that I need hands-on help, just relatively quick help. I can configure all this stuff on my own, just need to know what to troubleshoot and how.

Also it’s worth noting the new forum started out as a Private forum while I set up OIDC. I made it Public once I had it configured but I’m not sure if it’s fully Public. Perhaps there’s something I forgot to set and that’s why the users aren’t being created? In MediaWiki when it was doing a similar thing it was because I hadn’t enabled the ability for all user groups to autocreateaccounts.

I don’t think that’s possible in any SSO scenario that I know of.

So it doesn’t support adding the user to Discourse’s database at all!? My problem is the user gets redirected back to Discourse and, if they don’t have an existing user in Discourse’s database (for example my admin user account created during install), they get redirected as a guest and they basically logged in for nothing.

i.e

  • user goes to forum and lands at homepage as guest
  • they log in to keycloak
  • they get redirected back to discourse
  • they land on the homepage, UI shows they aren’t logged in.

And no user is visible in the admin Users list either in Discourse.

In fact, try for yourself and see what I mean. Try logging in “with OpenID Connect” and creating a Bit Phoenix Account. Your BP account will be created and everything and you’ll be able to log in just fine, but notice how you’re still logged out of Discourse? Yeah, me too. You’re not in the database.

Hmmm… I just gave it a try on your site and it does seem like something weird is going on. In theory it should pop up the registration dialog if a user account doesn’t already exist. We have many sites running with this plugin where this works correctly. Can you confirm that you’ve set up your site using our standard install guide, and do not have any other plugins/themes installed?

One possible suspect is your cloudflare proxy - please try disabling the ‘orange cloud’ in the cloudflare interface, give some time for DNS to propagate, and then try again.

3 Likes

Right, note that this is quite different than

Can confirm I don’t have any other themes or plugins installed. The only difference between my setup and the standard install is

  • CloudFlare - I’m not going to put direct load toward my server like that. I disabled it for now to test.
  • Apache - Discourse is sitting behind an apache2 virtual host acting as a reverse proxy.

Discourse itself exposes its internal port 80 to port 8082 on the docker host. The reverse proxy then listens on ports 80 and 443 and it deals with SSL. All requests to port 80 redirect you to 443, and 443 on hostname forum.bitphoenixsoftware.com is the reverse proxy in front of port 8082.

I do the same thing for auth.bitphoenixsoftware.com which is a reverse proxy sitting in front of Keycloak.

I do this so that I can run things like a LAMP stack (for the MediaWiki, blog, etc) on the same box as Keycloak and Discourse and have Apache be the Internet-facing web server for everything.

Cloudflare

I followed @david’s suggestion to disasble Cloudflare routing. This resulted in:

  • SSL certificate errors
  • Not fixing the issue. Still can’t log in or create an account.

My guess is it is the Apache reverse proxy.

Edit

@david, I see your login attempt in the Keycloak console log. Though the only warning/error is invalid_auth_credentials, indicating you probably typoed while logging in. So that’s definitely not related.

As far as errors on keycloak’s end related to me or my moderator, nadda. It’s all either just things like “that username doesn’t exist,” “invalid password,” etc.

Are there any other Discourse logs I can look at? I know I can look at /logs but even with verbose logging on there’s no errors when I log in. I do know it stops logging after verifying the JWT. Could that be related to my ssl errors with cloudflare off…? Last night it was getting far enough to log who logged in (username, email, etc).

Edit 2: @codinghorror To clarify what I meant by “automatically:” I meant, even if the user has to set up their discourse profile like you would with Google OAuth after logging in, the actual authentication is done through Keycloak. i.e, the user does not ever enter their password into Discourse’s UI.

Edit 3: :eyes: I see some weirdness in my rails production.log

Processing by Users::OmniauthCallbacksController#complete as HTML
  Parameters: {"state"=>"<redacted>", "session_state"=>"<redacted>", "code"=>"<redacted>", "provider"=>"oidc"}
Redirected to https://forum.bitphoenixsoftware.com/?
Completed 302 Found in 19ms (ActiveRecord: 7.5ms)

When signing into keycloak with a user whose Discourse account doesn’t exist yet. In theory this should trigger a UI prompting the user to complete registration, right? If so then why is it redirecting the user back to the home page with a ? at the end but no url params?

This is very, very strange.

Edit 4: I decided to just reinstall Discourse completely but retaining my app.yml. This time I will set it up as a public forum and not touch anything to do with login unrelated to OIDC.

That’s usually one of my troubleshooting steps lol, reinstall and hope like hell it works. A.K.A, operation: nuke everything.

I hope it works.

What I would to debug Keycloak is to remove Cloudflare and Apache. Start with a simple installation with let’s encrypt enabled. Getting two reverse proxies working correctly is complicated. (And anyway, it’s unlikely that a new community will need help from Cloudflare to handle the load. I’d wait until you have that problem to solve it.)

3 Likes

I can’t disable Apache. That’s not an option. I already have MediaWiki set up to work with keycloak and it’s working just fine. I can’t just have Discourse listening on port 80/443 with that going and I can’t even do that with keycloak going on the same box. The whole point of using the Apache reverse proxy in the first place was because I knew I was going to be running everything on the same box. I know the problem isn’t with cloudflare because… actually… the openID connect extension gets further into authentication/authorization with it on.

I can’t debug the Apache reverse proxy because I can’t turn it off without losing access to Keycloak.

Ah. I see. Then I’d spin up a DO droplet, get it configured there, and then move it back. Apache might not be the problem, but it’s best to know what it is that you’re debugging. I’m not sure, but I think that redirect is redirecting to the wrong place.

2 Likes

I can’t really spin up a DO droplet for myself. I mean I could use the one that’s hosting the old watercolorgames community that you set up @pfaffman but I don’t have any sort of ssh access to it. The new server I have is owned by someone else (it is a DO droplet too :D). This person has 4 droplets that they’re paying for but they only use 1, so they decided to give me one of their unused ones when he told me my domain was about to expire. That’s the server I’m putting the new discourse instance on.

Also, some additional things I’ve done:

There are no auth-related errors anywhere in rails production.log or /var/log/keycloak, no Apache errors. Disabling CloudFlare does nothing but screw up my SSL because I’m using their universal certificate for my entire domain, which in turn screws up Keycloak for everything.

I’m definitely on the same page with that redirect if you mean the one in the production.log where it’s redirecting to the Discourse instance’s index page. (I made that a link so I can include the ? at the end.)

Maybe @david would have a clue what’s up with that redirect?

Edit: Once we get this figured out I’m definitely gonna post a tutorial on how to set up Keycloak for OpenID-based SSO on Discourse on the same box. Maybe others will find it handy.

My suspicion with cloudflare was to do with their javascript ‘optimisation’ - in the past it has caused subtle issues like this. As @pfaffman said, the best way to check would be to spin up a temporary server with no other variables. If that’s not possible, you could try going to the “speed” tab on cloudflare and disable all of the options there.

2 Likes

I disabled the Brotli compression for HTTPS in that Speed section. Didn’t affect the speed at all and didn’t fix the issue. I’ll leave it disabled though. I wonder if there’s something to do with CloudFlare caching going on? Maybe I could disable the caching without routing through their network?

Edit: Enabled Cloudflare dev mode for the time being. So there’s no caching or speed increases going on at all. OpenID Connect is still not showing me the registration UI.

Edit 2: @dave I’d like to also point out that the whole time it HAS been working AS LONG as there’s an existing Discourse user account for OpenID Connect to merge with. So if I log in through OpenID Connect with a user named after my Discourse admin account or with the same email as it, I get my admin account.

Also I don’t have a token scope set in the settings. I don’t know what Keycloak calls those and I don’t know if I actually need it in this case. I don’t know how to set it up.

Edit 3: Weird. A few moments ago I got redirected to https://forum.bitphoenixsoftware.com/?filter=openid%20connect after logging in. Then my laptop died when I tried to post about it… and now it’s not happening anymore. I just got sent to the homepage again, no url parameters. When I did get sent to there though, there was no registration UI.

I’m wondering, is it supposed to go to that aforementioned URL? Or is there somewhere else it’s supposed to go? That’d be a big help. Perhaps there’s some Keycloak misconfiguration going on as far as URLs go. Let me try something.

Oh. I thought that you did. But password logins are denied; I didn’t check if you have an ssh key installed, but I guess you don’t. If you send me an ssh key (or better, stick one at github and send me your github username) I’ll let you in. You can do whatever you want with that droplet. It’s yours until whenever it is that year is up (and after that we can talk).

edit: My contact info is in my profile if for some reason you can’t find it.

Oh wonderful. Will do. That means i can pull uploads off it when i decide to move over.

Edit:

@pfaffman Thanks for getting my ssh key added. With the extra server I was able to isolate the bug to being unrelated to reverse proxies. I threw the droplet you set up on https://webber-server.bitphoenixsoftware.com/, left everything in the app.yml the same except for adding the openid-connect plugin, changing smtp settings to work with the new domain, and changing my From email to work with the new smtp server.

I let Discourse update while rebuilding (finally I can stop getting those emails :D) so I’m now on latest tests-passed on Webber Server. I configured OpenID Connect on it too to point to Keycloak on Cassian Server.

On Cassian Server, I reconfigured the redirect URI and other URIs in the discourse client to point to Webber Server.

In Keycloak:

In Discourse:

There is now a “Login with OpenID Connect” button on https://webber-server.bitphoenixsoftware.com/ (formerly https://community.watercolorgames.net/). Awesome. However, like on https://forum.bitphoenixsoftware.com/, no registration UI is shown when no Discourse user exists for the authenticated Keycloak user.

So, same exact issue! This rules out it being anything to do with Cloudflare or my Apache reverse proxy since neither are used for Webber Server. At least we’re narrowing it down to either a Keycloak config issue or a Discourse issue.

Also, yes. I name servers after characters from the MacGyver 2016 reboot. Deal with it.

MAJOR REVELATION: Webber Server has this in its Error Log…

(oidc) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected

Cross-site request forgery! Yay!

Another update:

@dave @pfaffman With the help of the extra server I was able to isolate the issue as having nothing to do with reverse proxies. After enabling CORS on Webber Server and adding auth.bitphoenixsoftware.com as a CORS origin, I no longer get CSRF errors and instead get the exact same outcome that I would logging into Cassian Server’s Discourse.

So…

  • you go to discourse as guest
  • you log in using openid connect
  • auth is successful but no discourse user exists for you
  • you get redirected to discourse with no error and no UI to complete your registration.
  • you now get put back on the homepage, as guest again.

Any updates on this? Since I’ve isolated the issue to either a discourse config or keycloak config issue, are there any other troubleshooting steps I can take?

I just fixed an issue relating to ‘full screen login’ registrations for open communities (login_required communities were not affected). Please try updating Discourse and see if that helps.

https://github.com/discourse/discourse/commit/49593d1a00a81f443a63fcc9409e891cc4c5e439

4 Likes

Woohoo! :smiley: This is like my second birthday (I just turned 17 this past Thursday.)

Time to throw on the drum n’ bass, watch discourse update, and see if it works.

Edit: Yep, that works. I can confirm it does on Webber Server. Now to get it working on Cassian Server which is a matter of changing redirect uris in Keycloak. Thank you SO much, everybody! :slight_smile:

4 Likes

Glad to hear it’s working, and happy birthday for last Thursday! :birthday:

If you do have some time to write a quick howto on this, I’m sure someone would find it handy in the future!

6 Likes