Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso)

DiscourseConnect is a core Discourse feature that allows you to configure “Single Sign-On (SSO)” to completely outsource all user registration and login from Discourse to another site. Offered to our pro, business and enterprise hosting customers.

:information_source: (Feb 2021) ‘Discourse SSO’ is now ‘DiscourseConnect’. If you are running an old version of Discourse, the settings below will be named sso_... rather than discourse_connect_...

The Problem

Many sites wishing to integrate with a Discourse site want to keep all user registration in a separate site. In such a setup all login operations should be outsourced to that different site.

What if I would like SSO in conjunction with existing auth?

The intention around DiscourseConnect is to replace Discourse authentication, if you would like to add a new provider see existing plugins such as: Discourse VK Authentication (vkontakte)

Enabling DiscourseConnect

To enable DiscourseConnect you have 3 settings you need to fill out:

enable_discourse_connect : must be enabled, global switch
discourse_connect_url: the offsite URL users will be sent to when attempting to log on
discourse_connect_secret: a secret string used to hash SSO payloads. Ensures payloads are authentic.

Once enable_discourse_connect is set to true:

  • Clicking on login or avatar will, redirect you to /session/sso which in turn will redirect users to discourse_connect_url with a signed payload.
  • Users will not be allowed to “change password”. That field is removed from the user profile.
  • Users will no longer be able to use Discourse auth (username/password, google, etc)

What if you check it by mistake?

See: Log back in as admin after locking yourself out with read-only mode or an invalid SSO configuration

Implementing DiscourseConnect on your site

:warning: Discourse uses emails to map external users to Discourse users, and assumes that external emails are secure. IF YOU DO NOT VALIDATE EMAIL ADDRESSES BEFORE SENDING THEM TO DISCOURSE, YOUR SITE WILL BE EXTREMELY VULNERABLE!

Alternatively, if you insist on sending unvalidated emails BE SURE to set require_activation=true, this will force all emails to be validated by Discourse. WE STILL STRONGLY ADVISE THAT YOU DO NOT DO THIS, so if you proceed with that setting enabled, you are assuming substantial risk.

Discourse will redirect clients to discourse_connect_url with a signed payload: (say discourse_connect_url is https://somesite.com/sso)

You will receive incoming traffic with the following

https://somesite.com/sso?sso=PAYLOAD&sig=SIG

The payload is a Base64 encoded string comprising of a nonce, and a return_sso_url. The payload is always a valid querystring.

For example, if the nonce is ABCD. raw_payload will be:

nonce=ABCD&return_sso_url=https%3A%2F%2Fdiscourse_site%2Fsession%2Fsso_login, this raw payload is base 64 encoded.

The endpoint being called must

  1. Validate the signature: ensure that HMAC-SHA256 of PAYLOAD (using discourse_connect_secret, as the key) is equal to the sig (sig will be hex encoded).
  2. Perform whatever authentication it has to
  3. Create a new url-encoded payload with at least nonce, email, and external_id. You can also provide some additional data, here’s a list of all keys that Discourse will understand:
    • nonce should be copied from the input payload
    • email must be a verified email address. If the email address has not been verified, set require_activation to “true”.
    • external_id is any string unique to the user that will never change, even if their email, name, etc change. The suggested value is your database’s ‘id’ row number.
    • username will become the username on Discourse if the user is new or SiteSetting.auth_overrides_username is set.
    • name will become the full name on Discourse if the user is new or SiteSetting.auth_overrides_name is set.
    • avatar_url will be downloaded and set as the user’s avatar if the user is new or SiteSetting.discourse_connect_overrides_avatar is set.
    • avatar_force_update is a boolean field. If set to true, it will force Discourse to update the user’s avatar, whether avatar_url has changed or not.
    • bio will become the contents of the user’s bio if the user is new, their bio is empty or SiteSetting.discourse_connect_overrides_bio is set.
    • title will set the user’s title.
    • website will set the user’s website on their profile.
    • location will set the user’s location on their profile.
    • profile_background_url will be downloaded and set as the user’s profile background if the user is new or SiteSetting.discourse_connect_overrides_profile_background is set.
    • card_background_url will be downloaded and set as the user’s card background if the user is new or SiteSetting.discourse_connect_overrides_card_background is set.
    • locale will set the user’s locale if the user is new and SiteSetting.allow_user_locale is enabled.
    • locale_force_update is a boolean field. If set to true alongside locale, it will force the locale to update for existing users (requires SiteSetting.allow_user_locale).
    • Additional boolean (“true” or “false”) fields are: admin, moderator, suppress_welcome_message, logout
  4. Base64 encode payload
  5. Calculate a HMAC-SHA256 hash of the payload using discourse_connect_secret as the key and Base64 encoded payload as text
  6. Redirect back to the return_sso_url with an sso and sig query parameter (http://discourse_site/session/sso_login?sso=payload&sig=sig)

Discourse will validate that the nonce is valid, and if valid, it will expire it right away so it can not be used again. Then, it will attempt to:

  1. Log the user on by looking up an already associated external_id in the SingleSignOnRecord model
  2. Log the user on by using the email provided (updating external_id) (unless require_activation = true)
  3. Create a new account for the user providing (email, username, name) updating external_id

Security concerns

The nonce (one time token) will expire automatically after 30 minutes. This means that as soon as the user is redirected to your site they have 30 minutes to log in / create a new account.

The protocol is safe against replay attacks as nonce may only be used once. The nonce is tied to the current browser session to protect against CSRF attacks.

Specifying group membership

If the discourse connect overrides groups option is specified, Discourse will consider the comma separated list of groups passed in groups.

Aside from groups, you may also specify group membership in your SSO payload using the add_groups and remove_groups attributes regardless of the discourse connect overrides groups option.

add_groups is a comma delimited list of group names we will ensure the user is a member of.
remove_groups is a comma delimited list of group names we will ensure the user is not a member of.

Reference implementation

Discourse contains a reference implementation of the SSO class:

A trivial implementation would be:

class DiscourseSsoController < ApplicationController
  def sso
    secret = "MY_SECRET_STRING"
    sso = DiscourseApi::SingleSignOn.parse(request.query_string, secret)
    sso.email = "user@email.com"
    sso.name = "Bill Hicks"
    sso.username = "bill@hicks.com"
    sso.external_id = "123" # unique id for each user of your application
    sso.sso_secret = secret

    redirect_to sso.to_url("http://l.discourse/session/sso_login")
  end
end

Transitioning to and from single sign on.

As long as the require_activation parameter is not set to true in the request payload, the system will trusts emails provided by the single sign on endpoint. This means that if you had an existing account in the past on Discourse with DiscourseConnect disabled, DiscourseConnect will simply re-use it and avoid creating a new account.

If you ever turn off DiscourseConnect, users will be able to reset passwords and gain access back to their accounts.

Real world example:

Given the following settings:

Discourse domain: http://discuss.example.com
DiscourseConnect url : http://www.example.com/discourse/sso
DiscourseConnect secret: d836444a9e4084d5b224a60c208dce14
Email validated: No (add require_activation=true to the payload)

User attempt to login

  • Nonce is generated: cb68251eefb5211e58c00ff1395f0c0b

  • Raw payload is generated: nonce=cb68251eefb5211e58c00ff1395f0c0b

  • Payload is Base64 encoded: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI=

  • Payload is URL encoded: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D

  • HMAC-SHA256 is generated on the Base64 encoded Payload: 1ce1494f94484b6f6a092be9b15ccc1cdafb1f8460a3838fbb0e0883c4390471

Finally browser is redirected to:

http://www.example.com/discourse/sso?sso=bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D&sig=1ce1494f94484b6f6a092be9b15ccc1cdafb1f8460a3838fbb0e0883c4390471

On the other end

  1. Payload is validated using HMAC-SHA256, if the sig mismatches, process aborts.
  2. By reversing the steps above nonce is extracted.

User logs in:

name: sam
external_id: hello123
email: test@test.com
username: samsam
require_activation: true

Unsigned payload is generated:

nonce=cb68251eefb5211e58c00ff1395f0c0b&name=sam&username=samsam&email=test%40test.com&external_id=hello123&require_activation=true

order does not matter, values are URL encoded

Payload is Base64 encoded

bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ==

Payload is URL encoded

bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ%3D%3D

Base64 encoded Payload is signed

3d7e5ac755a87ae3ccf90272644ed2207984db03cf020377c8b92ff51be3abc3

Browser redirects to:

http://discuss.example.com/session/sso_login?sso=bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ%3D%3D&sig=3d7e5ac755a87ae3ccf90272644ed2207984db03cf020377c8b92ff51be3abc3

Synchronizing DiscourseConnect records

You can use the POST admin endpoint /admin/users/sync_sso to synchronize a DiscourseConnect record, pass it the same record you would pass to the DiscourseConnect endpoint, nonce does not matter.

If you call admin/users/sync_sso from another site, you will need to include a valid admin api_key and a valid api_username in the request’s headers. See Sync DiscourseConnect user data with the sync_sso route for more details about how to structure the request.

Clearing DiscourseConnect records

If your external_id values from your DiscourseConnect provider have changed (perhaps you changed the generation algorithm, perhaps it’s a different endpoint) you can safely remove all the existing records using the rails console:

SingleSignOnRecord.destroy_all

Logging off users

You can use the POST admin endpoint /admin/users/{USER_ID}/log_out to log out any user in the system if needed.

To configure the endpoint Discourse redirects to on logout search for the logout redirect setting. If no URL has been set here you will be redirected back to the URL configured in discourse connect url.

Search users by external_id

User profile data can be accessed using the /users/by-external/{EXTERNAL_ID}.json endpoint. This will return a JSON payload that contains the user information, including the user_id which can be used with the log_out endpoint.

Existing implementations

  • The discourse_api gem can be used for SSO. Have a look at the SSO code in its examples directory to see a basic implementation.

  • Our WordPress plugin makes it easy to configure SSO between WordPress and Discourse. Details about setting it up are found on the SSO tab of the plugin’s options page.

Future work

  • We would like to gather more reference implementations for SSO on other platforms. If you have one please post to the Dev / SSO category.

Advanced Features

  • You can pass through custom user fields by prefixing the field name with custom. For example custom.user_field_1 can be used to set the value of the UserCustomField that has the name user_field_1.
  • You can pass avatar_url to override user avatar (SiteSetting.discourse_connect_overrides_avatar needs to be enabled). Avatars are cached so pass avatar_force_update=true to force them to update if the url is the same. Right now, you can’t pass an empty url to disable users’ avatar.
  • By default the welcome message will be sent to all new users created through SSO. If you wish to suppress this you can pass suppress_welcome_message=true
  • To configure your Discourse instance as a Discourse connect provider see: Using DiscourseConnect as an identity provider.

Debugging your DiscourseConnect provider

To assist in debugging DiscourseConnect you may enable the site setting verbose_discourse_connect_logging. By enabling that site setting rich diagnostics will show up in YOURSITE.com/logs. Be sure to :white_check_mark: the warnings box at the bottom of YOURSITE.com/logs.

We will log a warning to the logs with a full dump of the SSO payload:

:spiral_notepad: Need to automate user sign-ups? See Auto-provisioning user accounts when SSO is enabled

Last edited by @pedro 2026-05-27T21:27:39Z

Check documentPerform check on document:
176개의 좋아요
Discourse SSO + normal login
Sync DiscourseConnect user data with the sync_sso route
SSO login & logout issues
Is there a "log_in" SSO API endpoint?
SSO locked me out of Discourse!
What is the SSO login URL
With SSO my user still need to hit the login button
Auto-provisioning user accounts when SSO is enabled
SSO Login page not showing up
How to handle Discourse SSO when the authentication site allows users to change emails?
"User Log out API" return success in response but user session still alive
SSO integration & external profile sync help
Discourse SSO using auth0 via URL
SSO on Discourse using Atlassian Crowd
Mobile (firebase) SSO authentication
Login to Discourse with website account details
Single Sign-Out?
About the SSO category
Shibboleth / SAML / SSO -- Working Implementation for Higher Ed
How to generate nonce from client-side Javascript
Logout POST Request
Advantage and disadvantage of enabling SSO
Customized login auth plugin
Merging users from different forums
User Fields to validate users
Automatic session management with OAuth SSO
SSO and e-mail addresses having a plus sign
Automatically assigning users to a group
Users who register on my site, register also on Discourse Vise Versa
Custom Login / Registration from another API
Using existing RoR application for user auth / signup instead of discourse
SSO locked me out of Discourse!
Switching out authentication for a passwordless alternative
Enable sso for my site
Hashing Secret + Payload for SSO
SSO with TownNews CMS
Will Discourse ask for a username if it's not provided to /session/sso_login?
A way for admins to edit users' external IDs
Categorizing and tracking users
Discourse Ruby API testing "Unknown attribute 'auth_token' for User
Disable email verification for SSO
[PAID] Setup SSO for self-hosted instance
Getting signed data from the server
SSO and changing email addresses upstream
SSO (maybe) specific issue
SSO (maybe) specific issue
Why isn't Discourse more frequently recommended as a "community platform"?
Integration with .NET MVC application for a SaaS platform
Running my own discourse image
How do I make discourse use my platform's autentication system?
Automatic addition of users to group based on email domain
Allowing people to login using accounts from other websites
Seeking Slack Login / SSO for Discourse
Smooth J/K navigation when using keyboard
SSO to Joomla site
Discourse Connect on Local instance is not working
Implementing SSO for dev environment and troubleshoot
Login with FB, google and apple only
SSO provider implementation - Admin, moderator and groups ignored?
How to divide my community into 2 parts
Using Discourse to add a forum feature to our current application?
Shared cookie SSO: Notifying frontend
User auth with website at root and Discourse in subfolder
Can I authenticate to Drupal via Discourse?
Difficulty of Tiered-access forum
Any way to not require email verification with WP as the SSO Provider?
How to enable sso on discourse?
How to auto-login user in application web view
[PAID] automatically change user email
Create apikey for user programmatically as admin
Bug when visiting same thread url
Open source will support customized provider SSO
Is there a way to get all emails of users with the API?
How can generate _forum_session and _t for an user through code/api call or without login to browser?
Show/hide forums based on the domain? (Shared forum via CNAME)
Integrate with DjangoRest and Vue.js
Connect Discourse Auth with my Django user DB?
Disable account confirm emails when creating users via API
Transforming usernames with SSO
Automatically provision accounts with external SSO provider? (skip Create New Account prompt)
Error ArgumentError in DiscourseSsoController#sso, wrong number of arguments (given 1, expected 0)
Error ArgumentError in DiscourseSsoController#sso, wrong number of arguments (given 1, expected 0)
Embed variables in footer
Need help to setup SSO without emails
Programmatically log users out of discourse
How do I remove people from putting names? I have an API system I want in there
How to detect Discourse user on Ghost Blog?
Problem in sso redirection for compose a new pre-filled topic via URL
How to make default avatars and make sure nobody changes there avatar I want to set them an avatar with my API system
How might we better structure #howto?
Is Roblox Login Possible?
Discourse login with whmcs users
2.7.0.beta4: DiscourseConnect, Topic Timer UI revamp, Login Modal UI revamp, and more
Connecting Discourse invites to Marketo emails
Auto assign member to the certain group
Connecting to an external source of avatars?
Changing avatar_url while sso_overrides_avatar is set?
SSO - User Roles or ACLs to differentiate access levels
SSO - User Roles or ACLs to differentiate access levels
Disabling email verification
SSO Isnt working for me
Could Discourse offer a StackExchange-like SSO/Federated login service?
Mandatory username & avatar generation - How can we do this?
Intergrading discoures in to a application
Configure single sign-on (SSO) with WP Discourse and DiscourseConnect
How to connect to an external database running on localhost
Automate User Creation
Login Help - Correct way to login
What happens to my current users after configuring SSO?
SSO groups without completely overriding
JumpCloud LDAP/SSO
Usernames getting modified – numeral “1” being added
Is "partial" SSO possible?
Send an invite to a user but complete their profile programmatically
Magento 2 as SSO Provider?
Discourse SSO Provider doesn't redirect to return_sso_url as user logs in with custom SSO
Force password change after login
SSO and e-mail addresses having a plus sign
Would Discourse meet all of these niche needs to be a video game community forum?
OpenID Connect and SSO
Does `sso overrides groups` work with Oauth2?
Add user to group after purchase
Shibboleth SSO with Discourse
Using discourse forum in a native app (log-in, languages)
Discourse Connect: How implementing Discourse login with an existing database?
Sync group membership with external list of email addresses
Can I use my own Login page instead of discourse's Default login dialog box?
Modify the URL of 'create your account' button to an external site
How to add a custom url text link on the login page
Can discourse delete archived posts automatically and accept registration without email?
SSO is forcibly creating the user as an admin
Onboarding 15k Trial Users/Year: Need Help Streamlining the Process
Is DiscourseConnect available for self-hosted?
Is DiscourseConnect available for self-hosted?
How to Disable Required SSO Email Activation
User avatar selection through API no longer working
Wordpress plugin not redirect to discourse login automatically
Discourse login by cookie token
Custom field in discourseconnect
Logging users in through c++ desktop application
Invite only by email from database
Is it possible to autologin discourse via iframe?
Login w/ Discourse w/o SSO?
Wordpress plugin not redirect to discourse login automatically
Discourse Hosting Limits?
DiscourseConnect always returns "Nonce is incorrect, ..."
Has anyone succeeded in using discourse as sso provider for nextcloud? Share recipe?
SSO in C# .NET App
Intergrate Discourse with keycloak
Allow my application users to login to discourse
Feature: create default user name from email's user portion when using Google OAuth2/SSO
SSO login appears to have stopped working
Is there a way to use both local login and discourseConnect?
Discourse Hosting Limits?
Changing email addresses not working as an Admin
Populating email field on login page
Problem on SSO Login
SSO Broken - The requested URL or resource could not be found
Adding Discourse to existing Ruby on Rails site
Can I use DiscourseConnect along with Discourse Native Registration?
SSO Login with Discourse
Synchronize SSO login state between Discourse and provider
Connection and discourse account creation without going on discourse
Migrate an IPB 3.1 forum to Discourse
Disable DiscourseConnect
How to use Discourse Connect (SSO) to update avatar, username, name?
Label Sets
Unable to setup discourse in my windows 10
Embed Discourse comments on another website via Javascript
How admin user re-logins after using discourse connect sso and custom domain
How to "intercept" first time SSO usages to let users confirm the SSO action and set a username?
How to create a login on my front-end application to a specific Discourse site?
Use Discourse as an identity provider (SSO, DiscourseConnect)
Connect discourse with magento?
Users allowed to see only some categories
Admin status repeatedly revoked
Plugin to integrate Shopify accounts with Discourse
How to do single sign-on with forum program?
Simple login by email via deep links containing a username
How to set language for SSO users
Want to set internal forum on our reactjs member's platform
New instructions for SSO setup? "enable discourse connect" setting is missing
Add a new user via API
Configure GitHub login for Discourse
Use SSO to auto create Discourse login/password after signed up in my SaaS
How can I change the registration URL?
How do I go about making a very customized theme?
Is it possible to have an automatically updating link to a user's profile picture? Such as by giving each user one "slot" for an avatar?
SSO broken after rebuild with stable v3.3.3
Using Discourse Connect with a mobile app
Disable DiscourseConnect
Missing anchor links in certain TOC topics?
Integration into custom auth system where emails are not unique?
WP-Discourse not connected and admin email not recognized
How to disable SMTP during installation?
Auto Login to my Discourse site / subdomain
How to Disable activation_reminder email sending?
Communities using discourse SSO for their in-app community experience
Auth via Discourse Forum
🧩 How to Build an Android App User Community with Discourse? [HeyApks Project]
Postgres doesn't seem to be running when running Discourse locally using Docker
Discourse sso login redirect to localhost:3000, not 4200 (running via docker)
Cross-Discourse Quoting
Is it Possible to Send Encrypted Email and Password in the Authentication Flow?
Nutzung von Nextcloud aus Discourse heraus
Inherited forum with old Discourse Connect Config and Looking for Some Guidance
Merging user accounts
Understanding PII storage in Discourse
REQUEST: Highly Effective Age Assurance (OneID Phone No. Age Verification) Integration
Intergrate Discourse with keycloak
Auto-sign-in with the OpenId Connect Plugin and AWS Cognito
How can I configure Single Sign On for our App to the Discourse Community Forum
Auto-assign random, anonymous usernames
Extending header buttons
Login to Discourse with custom Oauth2 provider
Can I log into multiple instances of discourse simultaneously?
Upgraded last night and login button no longer works
SSO with Roles translating to Groups
Redirect login possible?
How to disable SSO via SSH
Connect Multiple WP Sites To 1 Discourse Installation?
What is the procedure to obtain CAS between my website and my discourse instance?
Problem logging in using SSO plugin
PAID: Create Open Source SSO plugin to auth with Wild Apricot
Trouble connecting drupal and discourse
About the idea: IDENTITY = EMAIL
About the idea: IDENTITY = EMAIL
Consequences of not validating email addresses
SSO and Restricted Groups
Questions about Discourse on Digital Ocean
Require users to join at least one group at sign-up
Use the same user database and login credentials in multiple discourse instances
How to connect my (existing) User Database?
User group sync with drupal
Options with SSO with another custom application
Issues in Integrating SSO in Discourse
How to implement Discourse with an already built Rails project
Updating SSO documentation
Configuring SSO to Work With SocialEngine
Updating SSO documentation
Discourse view file update does not reflect in browser
Discourse view file update does not reflect in browser
Trying to set up SSO
Discourse doesn't re-verify an address changed by SSO
Discourse doesn't re-verify an address changed by SSO
SSO and Discourse Consulting
Changing the unique key to identify users
Setting the user title(group?) based on the information that is coming from the sso payload
Advice needed for tailoring Discourse to my organisation
Primary and Discourse Site Integrations
Automatic Table of Contents generation
Questions Regarding Account Authentication Methods
Redirect all users who click on domain.com/signup to a different page
Poll Result Breakdown
Cant update email via API - invalid_access error
Disabling all emails except those registration related?
Can't get avatar overrides to work over SSO
Conflicting email addresses, giving admins more power to resolve issues
Which Discourse hosting tier should I choose?
New users via API if allow new unchecked
How to change login settings without being logged in?
Data explorer query to list the longest "estimated read time" topics?
Create user in discourse by redirecting from another site
HMAC-256 example on Official SSO page
Add links to meta.discourse.org instructions inside admin
How to configure the SSO Authorization URL via config (without using the admin panel)
TeamAndro exploring a migration from phpBB
DiscourseConnect payload hash encoding mismatch
Disabling SSO in development environment
Getting signed data from the server
Getting signed data from the server

안녕하세요. 어디서든 찾아보기가 어렵네요. 이 서비스는 어떤 프로토콜을 사용하나요? OAuth2를 가정해도 될까요? 매개변수가 일치하지 않는 것 같고, SSO 제공자에서 sso= 매개변수를 받는 것처럼 보이는 오류가 발생합니다. 도와주세요!

감사합니다.

DiscourseConnect는 Discourse의 SSO 구현입니다. 표준 프로토콜을 사용하지 않습니다.

PHP 코드를 살펴보는 데 문제가 없다면, 여기 예시 구현이 있습니다: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub.

네, 그렇게 하면 작동하지 않습니다. 사용자 인증에 사용하려는 OAuth2 제공자가 있다면 Discourse OAuth2 Basic 플러그인을 확인해 보세요.

1개의 좋아요

@simon 감사합니다. PHP 코드가 프로바이더이기도 한 건가요, 아니면 컨슈머인가요? 플러그인 영역에서 작동할 수 있는 OIDC 프로바이더도 봤고, ‘중개자(middle-man)’ 역할을 하는 프로바이더도 있었습니다.

SSO 프로바이더가 표준이 아니라면, 다른 시스템과 호환되지 않을 때 누구를 위한 것인가요?

다시 한번 감사합니다!

제가 링크한 코드는 WordPress를 Discourse의 인증 프로바이더로 사용하기 위한 것입니다.

WordPress 플러그인은 또한 WordPress를 DiscourseConnect 클라이언트로 사용할 수 있게 합니다: wp-discourse/lib/sso-client at main · discourse/wp-discourse · GitHub.

Discourse에 커스텀 SSO 구현을 추가한 동기가 무엇이었는지 정확히 알 수 없습니다. 비즈니스적 이유가 있었을 것으로 추정됩니다.

이것이 제공하는 이점 중 하나는 외부 사이트를 Discourse와 긴밀하게 통합할 수 있다는 점입니다. 예를 들어, 여기 나열된 모든 사용자 속성은 인증 과정에서 Discourse와 동기화할 수 있습니다: discourse/lib/discourse_connect_base.rb at 7b89fdead98606d4f47ceb0a1d240d0f6e5f589e · discourse/discourse · GitHub.

또한 OAuth2 또는 OpenID Connect 프로바이더로 설정되지 않은 사이트도 Discourse에서 사용자 인증에 사용할 수 있게 합니다.

단점으로는 인증 프로바이더 사이트에 일부 커스텀 코드를 추가해야 한다는 점이 있습니다.

1개의 좋아요

안녕하세요, SSO를 제공하는 외부 사이트에서 이메일 주소를 인증하지 않을 때 어떤 문제가 발생하는지 궁금합니다. 자동화된 스팸 발송을 가능하게 하는 것만 그런가요? 아니면 다른 고려 사항도 있나요? 외부 사이트가 이메일 인증을 하지 않는 경우, 왜 Discourse가 이메일 인증을 처리하도록 권장되지 않는지 궁금합니다.

추가적인 통찰을 주시면 감사하겠습니다.

제가 알고 있는 최악의 시나리오는 다음과 같은 조건이 필요합니다:

  • 외부 사이트에서 이메일 주소가 검증되지 않은 경우
  • SSO 페이로드에 require_activation=true가 설정되지 않은 경우
  • Discourse 사이트에 SingleSignOnRecord가 연관되어 있지 않은 기존 계정이 있는 경우 (계정 소유자가 SSO를 사용하여 Discourse에 로그인해 본 적이 없는 경우)

이러한 경우, 누군가 SSO로 로그인해 본 적이 없는 Discourse 사용자의 이메일 주소를 사용하여 외부 사이트에서 가입할 수 있습니다. 그러면 외부 사이트의 미검증 계정이 동일한 이메일 주소를 사용하는 Discourse 계정을 탈취할 수 있게 됩니다. 해당 계정이 Discourse의 관리자 계정이라면 특히 심각한 문제가 됩니다.

실제로 외부 사이트가 이메일 검증을 처리하지 않는 경우, Discourse가 이메일 검증을 처리하도록 권장됩니다:

다만, 이메일 검증을 외부 사이트에서 처리하는 것이 더 좋은 이유는 몇 가지 있습니다:

  • 사용자에게 Discourse에서 확인 이메일을 받도록 강제하면 사용자가 처음 Discourse에 로그인하려고 할 때 일부 마찰이 발생합니다. (현실적으로 그 마찰은 어딘가에서 발생해야 합니다 - Discourse 측이거나 외부 사이트 측일 수 있습니다.)
  • SSO 페이로드에 require_activationtrue로 설정되어 있으면, Discourse는 이메일 주소에 기반하여 기존 Discourse 계정을 외부 로그인과 일치시키지 않습니다. 이는 일부 계정이 사용자명/비밀번호로 등록되어 Discourse에 생성된 후에 DiscourseConnect를 활성화할 경우 문제가 됩니다. 또한 어떤 이유로든 Discourse에서 SingleSignOnRecord 항목을 삭제해야 할 경우에도 문제가 됩니다. 사용자가 Discourse에 다시 로그인하려고 할 때 Discourse가 자동으로 새 SingleSignOnRecord 항목을 생성하지 않기 때문입니다.
4개의 좋아요

감사합니다, @simon - 정말 유용합니다!

안녕하세요, SSO 페이로드의 groups 필드에 대해 질문이 있습니다.

자동 그룹(관리자, 모더레이터, 신뢰 수준 등)도 덮어쓰기(overwrite)되나요? 아니면 유지되나요?

아니요! 해당 설정의 설명이 정확하다면, 수동 그룹에만 영향을 미칩니다.

아.. 설명에 '수동’이라는 단어를 못 봤네요. 제 사용 사례에 딱 맞는 것 같아서 한번 시도해 보고 결과 알려드릴게요.

1개의 좋아요

이 내용을 읽었을 때, base64로 인코딩된 페이로드에서 직접 서명을 생성해야 한다고 생각했습니다. UTF-8 바이트에서 생성해야 한다는 점을 몰랐습니다. 이 부분을 좀 더 명확히 설명해 주실 수 있을까요?

DiscourseConnect를 사용해보고 있습니다. 문서가 정말 잘 되어 있어서 감사합니다.
하지만 몇 가지 막히는 부분이 있어서 도움이나 설명을 부탁드립니다.

우리는 사용자가 Discourse 로그인으로 WordPress에 로그인할 수 있기를 원합니다(이 부분은 잘 작동하고 있습니다 :slight_smile: ). 그런데.

  • Discourse 가입 시 WordPress 사용자를 생성할 수 있나요? (사용자가 Discourse 계정을 만들면 자동으로 WordPress 계정/프로필도 생성되어 WordPress에 로그인할 수 있도록 하는 것)

  • WordPress 사용자 그룹과 Discourse 그룹을 동기화할 수 있나요?
    사용자가 WordPress와 Discourse 계정을 모두 가지고 있는 경우, DiscourseConnect는 두 계정을 연결할 수 있습니다. 하지만 동일한 이름의 Discourse 그룹에 속한 사용자에게 WordPress 계정에는 해당 사용자 그룹을 부여하지 않으며, 그 반대도 마찬가지입니다(그룹 이름이 서로 다른 경우怎么办呢? 사용자가 Discourse 그룹 'Group for Testing Things’에 속해 있을 때, DiscourseConnect에 사용자 그룹 'Testing Group’을 부여하도록 어떻게 지시할 수 있나요?)

무엇을 놓치고 있는 걸까요?

정답은 모르지만…

이 부분은 주의가 필요합니다. 이는 어딘가 불법적인 영역에 해당하며, (물론 사이트 소유자의 경우를 제외하면) 사용자 동의나 인지 없이 이루어지고 동시에 데이터가 다른 곳으로 이동하기 때문에 상당히 광범위하게 나쁜 관행으로 간주됩니다. :smirking_face:

물론 이는 회색 지대에 해당하며, 기본적으로 예를 들어 구글도 그렇게 하고 있습니다.

하지만… 왜 그런 걸까요? 워드프레스 쪽에서 로그인을 Discourse SSO로만 제한하고, 계정 생성 시 사용자를 Discourse로 리다이렉트하면 됩니다. AFAIK(내가 아는 한) 기본 설정으로는 사용자 계정을 자동으로 동기화할 수 없습니다. 그리고 왜 그렇게 해야 하느냐면, SSO를 사용하면 사용자가 필요할 때 자동으로 이루어지기 때문입니다.

우리의 시나리오(회원제 조직)에서는 다음과 같은 구조를 사용하고 있습니다.

  • WordPress는 구독 관리, WordPress 스토어에서 상품 구매, 그리고 User Groups를 통해 회원이 조직 내에서 수행할 수 있는 작업을 관리하는 데 사용됩니다.
  • Discourse는 포럼/온라인 커뮤니티로 사용되며, Groups를 통해 사용자가 Discourse의 어떤 영역에 접근할 수 있는지 제어합니다.

현재 새 회원은 WordPress 계정(구독 설정 등 포함)을 생성해야 하고, 별도로 Discourse 계정도 생성해야 합니다. 또한 User Group과 Discourse Groups는 수동으로 관리/동기화되고 있습니다.

새 사용자가 한 번만 설정을 하면 두 계정이 모두 생성되고, User Group과 Discourse Groups가 자동으로 동기화되는 해결책을 찾고 있습니다. API 등을 활용하여 그룹 동기화는 해결할 수 있을 것으로 생각합니다. 제가 해결하거나 방지하고자 하는 문제는 여러 사용자 계정 설정을 통합하는 부분입니다.

현재 하시는 작업은 Discourse를 WordPress의 SSO 제공자로 사용하는 것 같습니다. 이 방식은 여기에서 설명되어 있습니다: Discourse를 ID 제공자(SSO, DiscourseConnect)로 사용하기. Discourse WordPress 플러그인은 Discourse를 위한 SSO 제공자로 WordPress를 사용하거나, WordPress를 위한 ID 제공자로 Discourse를 사용하는 두 가지 옵션을 제공합니다. 두 방식 모두에 동일한 이름을 사용하다 보니 혼란이 생기는 경우가 있습니다.

이 경우 WordPress를 ID 제공자로 사용하는 것이 더 적절할 것 같습니다. 이 방식을 사용하면 사용자는 WordPress 사이트에서 계정을 생성한 후 WordPress 자격 증명으로 Discourse에 로그인하게 됩니다. 이 방식에서 주의할 점은 사용자가 WordPress를 통해서만 Discourse에 로그인할 수 있다는 것입니다. 즉, 이미 WordPress 계정이 없다면 Discourse 계정을 생성할 수 없습니다. WordPress 회원 사이트와 Discourse를 통합할 때 이것이 적절한 설정이라고 생각합니다.

WordPress가 Discourse의 ID 제공자로 사용될 때, 사용자의 WordPress 활동에 기반하여 사용자의 Discourse 그룹 멤버십을 설정하는 데 유용한 유틸리티 함수가 몇 가지 있습니다. 해당 함수는 여기에서 설명되어 있습니다: WP Discourse SSO를 사용하여 Discourse의 그룹 멤버십 관리.

원래 질문으로 돌아가 보겠습니다:

WordPress 플러그인의 DiscourseConnect 클라이언트 코드를 살펴본 지가 오래되었지만, 질문하신 내용은 해당 코드가 작동하도록 기대하는 방식과 거의 일치한다고 생각합니다. 사용자가 Discourse 계정을 가지고 있다면, WordPress에서 “Discourse를 통해 로그인” 링크를 클릭하기만 하면 해당 사용자를 위한 계정이 생성됩니다.

WordPress를 DiscourseConnect 클라이언트로 사용하는 경우 기술적으로 가능하지만, 변경 사항이 없는 한 문서에 링크한 add_user_to_discourse_groupremove_user_from_discourse_group 메서드를 사용할 수 없습니다. 사용자가 Discourse 그룹에 추가될 때 트리거되는 Discourse 웹훅을 설정하고, 그 웹훅을 처리하기 위해 WordPress에 코드를 추가하는 등의 조치가 필요합니다. WordPress에서 Discourse로 그룹을 동기화하려면, WordPress에서 변경 사항이 있을 때 사용자의 그룹을 업데이트하기 위해 Discourse에 API 호출을 해야 합니다. 따라서 WordPress를 DiscourseConnect 제공자로 사용하는 경우 비교적 쉽게 달성할 수 있는 작업이, WordPress를 DiscourseConnect 클라이언트로 사용하는 경우 다소 복잡해질 수 있습니다.

1개의 좋아요

다만, 커스텀 로그인이 사용되는 경우를 제외합니다. WooCommerce/멤버십/LLM과 같은 상황에서 해당 버튼을 표시하고 Discourse SSO를 유일한 제공자로 강제하는 기능은 기본적으로 제공되지 않으며, 커스텀 작업이 필요합니다.

해결해야 할 문제가 몇 가지 있습니다. 하나는 캐싱과 관련이 있고, 다른 하나는 일부 플러그인이 추가하는 로그인 리다이렉트와 관련이 있습니다. 이러한 문제에 직면한 분은 Support > WordPress 카테고리에 질문해 주세요. 보통 쉽게 해결됩니다.

답변을 드리지 못한 점 죄송합니다. 말씀하신 대로 정확히 작동하며, 수동 그룹에만 영향을 미칩니다.

@simon 님, 안녕하세요.

이 SSO 기능에 대한 POC 탐구 과정에서 발생하는 404 응답에 대해 정말 도움이 필요합니다. 이 문제를 하루 종일 연구했지만 아직도 원인을 파악하지 못하고 있습니다. 저는 다음 단계를 수행했습니다:

  1. discourse_connect 활성화
  2. discourse_connect_url을 https://localhost:4200/login으로 설정 (간단하게 유지하기 위해)
  3. discourse-connect secret: 20자 (1) 1111111111111111111로 설정

그 후 Angular 앱의 로그인 페이지에서 다음 코드를 따라 요청을 보냈습니다:

하지만 404 not found 응답을 받았습니다.

제 이해로는, admin/users/sync_sso 엔드포인트에 POST 요청을 보낼 때, 사용자가 discourse에 존재하지 않는다면 user_id와 email을 기반으로 새 사용자가 생성되어야 하고, 반환된 결과는 404 상태 코드를 가진 빈 객체가 아닌 사용자 객체여야 합니다.
로그도 확인해 보았지만, 이 실패한 응답과 관련된 정보를 제공하지 않았습니다.

도움 주시면 감사하겠습니다!