Discourse OAuth2 Basic

5 posts were split to a new topic: What is supposed to go in “DISCOURSE_HOST”?

Love this plugin, thank you so much!

Managed to get this working with roblox beta auth 2.0:

Hello,
We are trying to integrate Discourse with our application using OAuth2 Basic but we are getting the following error in the logs:
Note: We are using NGROK as we are debugging the connection.

OAuth2 Debugging: request POST https://formshare.ngrok.io/oauth2/token

Headers: {"User-Agent"=>"Faraday v1.9.3", "Content-Type"=>"application/x-www-form-urlencoded", "Authorization"=>"Basic S2k2SFZtTVpuSTFHUExiRXVlWVJDNENiOkNvb1k0anlQemt3dWNRV21Sa2FWOVNnbHZLbjJFT3cxc3BIMmtMck9yY21vNDM4Tg=="}

Body: {"client_id"=>"Ki6HVmMZnI1GPLbEueYRC4Cb", "client_secret"=>"...some_secret_...", "grant_type"=>"authorization_code", "code"=>"5pPCrsp0pZ84373MNaHh2cuskfc8AlbfmdwMBFIVW4n4z9aX", :redirect_uri=>"https://community.formshare.org/auth/oauth2_basic/callback"}

------------------

OAuth2 Debugging: response status 200

From POST https://formshare.ngrok.io/oauth2/token

Headers: {"content-length"=>"108", "content-type"=>"text/html; charset=UTF-8", "date"=>"Thu, 01 Sep 2022 21:42:08 GMT", "ngrok-trace-id"=>"79cdc3f1c3eae5e37a30796aebbf9bd6", "server"=>"gunicorn"}

Body: {"token_type": "Bearer", "access_token": "p0FVuwjSXL1ZINEklMAVqUlpZxSll1SgnbpE8YWP4C", "expires_in": 864000}

-----------------------------------

(oauth2_basic) Authentication failure! invalid_credentials: OAuth2::Error, {"token_type": "Bearer", "access_token": "p0FVuwjSXL1ZINEklMAVqUlpZxSll1SgnbpE8YWP4C", "expires_in": 864000}

We left the params “oauth2 callback user id path” and " oauth2 callback user info paths" empty.

Any idea is appreciated.

Can I use this to authenticate with Microsofts XBL service?

I presume the logic would be similar to this?

Hi everyone. I try to configure this plugin with our internal Oauth2 server with authorization code flow.

When a user click “Connect with Oauth”, the /authorize endpoint works and a code is return to the callback. But then Discourse shows a generic 500 error " Oops. The software powering this discussion forum encountered an unexpected problem" and the /token endpoint is not accessed.

The error log says so:
OAuth2::ConnectionError (FinalDestination: all resolved IPs were disallowed) lib/final_destination/ssrf_detector.rb:74:in lookup_and_filter_ips' lib/final_destination/http.rb:13:in connect’ lib/midd

hostname discourse-app
process_id 653
application_version 702f27e6ee10ac257f5fee3f331d05f5fa5d7a45
HTTP_HOST *****
REQUEST_METHOD GET
HTTP_USER_AGENT Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
HTTP_REFERER *****
HTTP_X_FORWARDED_FOR *****
HTTP_X_REAL_IP *****
time 10:25 pm
params
code def50200babf84f7376f99fefa34369d876566b6bc0a341d8fba431999a72549ac06f6aad01df6fa43061707c525ba5d725ad
state 20139e0a134a5972566d4ddb6f7f9092a2cddb9e5216973a

As I understand there is an issue with some IP address? Currently the Oauth2 server is hosted on my dev environment (localhost) and the authorize and token endpoints are configured accordingly. Is it a problem?

Found the problem:

  1. For some reason the /token endpoint was never called. After filling a maximum of options in admin parameters related to oauth the endpoint was called without answer
  2. I forgot that it was the Discourse server that would call the /token endpoint and not the webclient. Therefore, the server could not reach my localhost Oauth2 server. Putting our Oauth2 server behinf a domain solved the problem

Now, I can connect existing users but don’t undersand how to sign in new users through this plugin.
If the user sign in with oauth, it gets an error saying he has no active account on Discours server. Which is normal since it’s a new user.

Is there a dedicated callback to sign in user instead of login? Or a specific parameter to set to allow account creation?

My company oauth server was generating a /profile JSON response with a little typo in one field. Everything was okay after fixing the typo.
But I have to say that Discourse logs can be very misleading! Nothing was wrong with the callback.

Hi team,

I’m having an issue with pulling the ID I need for my user JSON request from the authorization response. In reading the documentation it appears that the account ID is sent in a nested array:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"Bearer",
   "expires_in":1800,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "permissions":[
      {
        "accountId":123,
        "availableScopes":["contacts_view", "contacts_me", 
"contacts_edit", "finances_view", "events_view"]
      }
   ]
}

I’ve tried setting the oauth2 callback user id path to permissions[0].accountId but my uid value is always blank. Unfortunately, calls to pull the user json require this accountId in the JSON url.

I was able to get this working by passing permissions.first.accountId, I found that when I passed permissions into a test property the array was already parsed as a Ruby array. Unfortunately, the fields seem to reject the Ruby syntax to call array elements and any attempt to use Javascript syntax would result in a TypeError String to Integer. Luckily Ruby had the syntax above, is this the intended method?

I just got this to work with Authentik OAuth2, however there were some hiccups with the oauth2 user json url setting. I used the user_info endpoint of Authentik for that (/application/o/userinfo/), however I did not know how to map the fields. For anyone looking how to set up Discourse with Authentik’s OAuth2, here’s the summary:

  • User id path: preferred_username
  • Username path: preferred_username
  • Name path: name
  • Email path: email
  • Email verified path: email_verified
  • Avatar: empty.

I had the following issues:

  1. At the beginning, I forgot the trailing slash in the json url https://DOMAIN/application/o/userinfo/. This lead to the user info request (permalink to the source) to return a 301 HTTP code, which caused the login to fail. I do not know whether the trailing slash should be there by spec, but perhaps it would be good to handle 301 correctly.
  2. Debugging this turned out tricky. The oauth2 debug auth settings was a lifesaver but… Logster truncates the debug log before actually dumping the meaningful response data. I had to modify manually in the container the log line to
    log("user_json_response: #{user_json_response.status} #{user_json_response.headers} #{user_json_response.body}")
    
    Perhaps that log line could be updated? I guess it could help other people figure out the json attributes path.
2 Likes

I just set up Auth0 with the plugin and found that avatars are not picked up.

These are the relevant settings:

  DISCOURSE_OAUTH2_ENABLED: true
  DISCOURSE_OAUTH2_CLIENT_ID: '${DISCOURSE_OAUTH2_CLIENT_ID}'
  DISCOURSE_OAUTH2_CLIENT_SECRET: '${DISCOURSE_OAUTH2_CLIENT_SECRET}'
  DISCOURSE_OAUTH2_AUTHORIZE_URL: '${DISCOURSE_OAUTH2_ISSUER}/authorize?connection=xxx&login_options=yyy'
  DISCOURSE_OAUTH2_TOKEN_URL: '${DISCOURSE_OAUTH2_ISSUER}/oauth/token'
  DISCOURSE_OAUTH2_USER_JSON_URL: '${DISCOURSE_OAUTH2_ISSUER}/userinfo'
  DISCOURSE_OAUTH2_SCOPE: 'email openid profile'
  DISCOURSE_OAUTH2_JSON_USER_ID_PATH: 'sub'
  DISCOURSE_OAUTH2_JSON_USERNAME_PATH: 'nickname'
  DISCOURSE_OAUTH2_JSON_NAME_PATH: 'name'
  DISCOURSE_OAUTH2_JSON_EMAIL_PATH: 'email'
  DISCOURSE_OAUTH2_JSON_EMAIL_VERIFIED_PATH: 'email_verified'
  DISCOURSE_OAUTH2_JSON_AVATAR_PATH: 'picture'
  DISCOURSE_OAUTH2_EMAIL_VERIFIED: true
  DISCOURSE_OAUTH2_OVERRIDES_EMAIL: true
  DISCOURSE_OAUTH2_ALLOW_ASSOCIATION_CHANGE: false

In the debug log I can see that the picture element is set in the JSON response, but the user’s avatar does not change, neither for new nor for existing users.

What did I miss?

What is the best way to replace the icon on the login button with either another icon or an image?

.btn-social.oauth2_basic:before {
    content: url('https://www.contoso.com/path/to/image');
}

.btn-social.oauth2_basic > svg {
    display: none;
}

feels sufficient but a bit hacky

2 Likes

It seems like the plugin only updates the avatar/username on initial creation of the user, not on everytime they log in.

Is there anyway to fix this and have the plugin update the avatar as well on login/reconnection?

You can use the auth overrides email, auth overrides username and auth overrides name settings to make those things apply on future logins. I’m afraid we don’t currently have a similar setting for avatars, but it would be pr-welcome

1 Like

Thank you! I actually found these later on. I forked the repo and added my own versions to get this functioning with Roblox, which included the override for avatars. Which I believe just uses DiscourseConnect avatar override so people can’t change it.

One thing I wish though is that roblox does not provide a email on OAuth so I sadly need to have them signup with a email. but thats a non issue for yall haha.

A post was split to a new topic: Twitter login doesn’t work on meta

Does anyone know if this still works?

Yes. I’m confident this plugin works. :+1:

1 Like

Hi, I was able to intergrate this plugin in my discourse discuss.frontendlead.com, I am using teachable oauth OAuth Quickstart Guide

However, I only want to allow people to be able to successfully register if and only if they have a current paid account on teachable. I would imagine, I need to add custom functionality in the plugin to handle this? I am wondering, can you guys or even I can, introduce another field on the settings called custom code after oauth, which allows developers to perform specific actions after signing up? Or if there are better suggestions, please let me know.

Edit: I forked the repo and got it working here:

If someone else using teachable is trying to do the same, my repo would work out of the box, the only thing is if you didn’t buy a course, it will say you need to go to my domain to purchase it. you may want to update that for your own usecase.

1 Like

That’s great!

There’s a similar situation with OAuth2 registration with the Discourse Patreon plugin. When “Login with Patreon” is enabled, it allows anyone with a Patreon account to register on the Discourse site. What site owners generally want is to only allow their supporters to be able to register Discourse accounts. I wonder if details are returned from Patreon that would allow similar logic to be added to Patreon authentication?

1 Like