Can you please help me with WP SSO? (Official SSO for Discourse plugin

wordpress

(Holden) #1

Hello,

I’m new to Discourse and I’m trying to setup SSO for Discourse / WP, but I’m confused by some settings. I searched for a Discourse / WP SSO ‘how to’ but couldn’t find one. Can someone please tell me what I should enter/check for the following fields? I’ve included a screenshot of the ‘login’ page below.

Thanks in advance,

Holden

enable sso

enable sso provider

sso secret (I SET THIS UP OKAY)

sso overrides email

sso overrides username

sso overrides name

sso overrides avatar

sso not approved url


(Holden) #2

It seems I got it to work :smile:

Thanks @etc Your instructions on your WP plugin page helped:

“3. Enabling SSO on Discourse
In your Discourse admin settings, find the settings labeled, enable_sso, sso_url and sso_secret. Enter the URL of your WP installation, as well as the secret key, and enable sso.”


(etc) #3

Glad you got it figured out :slight_smile: Please don’t hesitate to tag me again if you have a question.


(Holden) #4

Thanks @etc I appreciate it! I looks like I have a few questions…

I’ve been testing my Discourse / Wordpress installation using the Official SSO for Discourse plugin and I’m not sure if SSO is working correctly. Can you please let me know what you think?

The Discourse login seems to work:
When I click ‘Log In’ on Discourse I’m forced to login on WordPress, and then I’m directed back to Discourse.

However, I’m not sure if the WordPress login works:
When I login to WordPress, and then go to Discourse, I’m not logged in to Discourse. When I click the Discourse Log In button, it logs me in automatically (I don’t have to enter credentials and it doesn’t send me to the WP login page). Is it supposed to function this way or should I be logged in?

Log Out does not seem to work:
When I log out of one system it doesn’t log me out of the other. I expected that logging out of one would log me out of both.

Is my installation functioning correctly? If not, do you have any suggestions? Here are my current Discourse and WP SSO settings:

Discourse > Admin > Settings > Login
enable local logins - checked
allow new registrations - checked
enable sso - checked
sso url - https://www.example-wordpress-site.com/
sso secret - secret_key
sso overrides username - checked
log out strict - checked

WordPress > APC > Settings > Discourse:
Enable SSO - checked
SSO Secret Key - secret_key

Thanks for your help!


(etc) #5

Are you referring to the PT Discourse SSO plugin or the Official Discourse Plugin (which isn’t just SSO)?

But yes, how you describe is fortunately/unfortunately how SSO works.

Even though it is single sign on, your sessions are separate on each system. The only thing that happens is your WP installation is used to authenticate the session, but once that session is active, it is independent on each.

You could probably extend the plugin so that when you log out of WordPress, you also log out of Discourse, but that would likely require a Discourse plugin as well to send you back to the WP installation after the session is destroyed.


(Holden) #6

Okay, that makes sense.

I’m referring to the Official Discourse plugin, not your PT plugin. I’m using the official one because I want to use Discourse for comments.

I’m taking the Ruby on Rails course at gotealeaf.com When I complete it in 4-5 months maybe I’ll try my hand at creating a Discourse plugin to handle logouts.

Thanks again for your help!


(Kane York) #7

To do this, you need an interstitial after the WP login. It should look like this:

<body>
Some message saying please wait
Maybe a <div class=spinner>
<embed src="https://discourse.example.com/session/sso" onload="window.location = '/login-finished.php';">
</body>

(Jeff Atwood) #8

Don’t we do this for some of our customers, @techapj?


(Neil Lalonde) #9

I know that one customer does that. @techAPJ or @AdamCapriola would know how it’s done.


(Adam Capriola) #10

Yup logouts are doable. It’s a two-part implementation.

###Logout Initiated from WordPress

Pro tip: Fill in the three variables ($discourse_url, $api_key, and $api_username).

/**
 * Logout Sync
 * 
 */
add_action( 'clear_auth_cookie', 'ac_discourse_logout' );

function ac_discourse_logout() {

	// Variables
	$discourse_url = DISCOURSE_URL;
	$api_key = DISCOURSE_API_KEY;
	$api_username = DISCOURSE_API_USERNAME;

	global $current_user;

	//
	// Get Discourse ID
	//

	// URL
	$url = sprintf(
		'%s/users/%s/activity.json',
		$discourse_url,
		$current_user->user_login
	);

	// cURL
	$ch = curl_init();
	curl_setopt( $ch, CURLOPT_URL, $url );
	curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
	$body = curl_exec( $ch );
	curl_close( $ch );

	// Interpret results
	$json = json_decode( $body, true );

	// Check for ID
	if ( ! isset( $json['user']['id'] ) ) {
		return;
	}

	//
	// Log out
	//

	// URL
	$url = sprintf(
		'%s/admin/users/%s/log_out?api_key=%s&api_username=%s',
		$discourse_url,
		$json['user']['id'],
		$api_key,
		$api_username
	);

	// Parameters
	$parameters = array(
		'username_or_email' => $current_user->user_email
	);

	// cURL
	$ch = curl_init();
	curl_setopt( $ch, CURLOPT_URL, $url );
	curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $parameters ) );
	curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
	curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'POST' );
	$body = curl_exec( $ch );
	curl_close( $ch );

}

###Logout Initiated from Discourse

Discourse setting: “logout redirect” = http://example.com/?request=logout

/**
 * Process SSO Logout Request
 * 
 */
add_action( 'parse_request', 'ac_parse_request_logout' );

function ac_parse_request_logout() {

	// Check for logout request
	if ( isset( $_GET['request'] ) && $_GET['request'] == 'logout' ) {
	
		wp_logout();

		wp_redirect( 'http://discourse.example.com' );
		exit;

	}

}

(etc) #11

Fantastic work, Adam - as always! I wasn’t aware of the logout redirect setting.

I think I’ll add these options to the PT plugin. Thanks!


(Holden) #12

Thank you @AdamCapriola This is great!

Is there a way to update Discourse so a user is logged in automatically if they login to WP first?

This describes the current login process:


(Adam Capriola) #13

Check out my guide here:

This is part of it:

/**
 * Add user meta to signify the user has just logged in
 * 
 */
add_action( 'wp_login', 'ac_fresh_login', 10, 2 );

function ac_fresh_login( $user_login, $user ) {

	update_user_meta( $user->ID, 'fresh_login', 1 );

}

/**
 * One-time Discourse SSO iframe
 * 
 */
add_action( 'wp_footer', 'ac_discourse_sso_iframe' );
add_action( 'admin_footer', 'ac_discourse_sso_iframe' );

function ac_discourse_sso_iframe() {

	// Only show iframe on first page the user hits after logging in
	
	$fresh_login = get_user_meta( get_current_user_id(), 'fresh_login', true );

	if ( $fresh_login == 1 ) {

		echo '<iframe src="' . DISCOURSE_URL . '/session/sso" width="0" height="0" tabindex="-1" title="Discourse SSO" style="display:none" hidden></iframe>' . "\n";

	}

}

Then you need to delete the fresh_login user meta somewhere along the way. (I prefer after validation, or you could do it in the iframe function instead.)


(Vanina Yordanova) #14

The plugin is really nice but the is something I cannot understand.

If I use Woprdress as SSO provider and disable the email verification from the DIscourse side, were a user be able to log in to Discourse, even he did not verify his account if Wordpress???

Thanks :slight_smile:
@etc


(etc) #15

No, unfortunately the account needs to be activated with WordPress first. You’ll need to disable account activation if you don’t want that.