Redirecting back to WordPress after signing in with Discourse SSo

I am helping someone to use their WordPress website set up as an SSO client to their Discourse forum with the WP-Discourse plugin. They would like to make the website accessible only to logged-in users.

I tried using the Restricted Site Access plugin to achieve this. I set it up so that it shows a page with the URL auto-generated by the WP-Discourse login shortcode; it seems however that the access plugin is restricting you from redirecting to the Discourse login page.

Is there a better way to do this? A different plugin for restricting access perhaps? The goal is to have un-authenticated users land on a page that describes the site and links to the Discourse SSO page where they can either create an account or sign in. After this, they should be redirected back to the site homepage (which will now be visible because they’re logged in).

Any help is greatly appreciated! cc @supermathie @simon

3 Likes

It should be possible to get this working. I’ll take a look at it and let you know what I find.

3 Likes

The issue with the Restricted Site Access plugin is that it restricts access to all of WordPress except for the page that you have set as the Restricted Notice Page. This prevents the WP Discourse plugin SSO client functionality from working. Fortunately, the Restricted Site plugin has lots of filters that you can hook into to customize its behaviour.

To get it to work, you’re going to need to add a couple of functions to either your theme’s functions.php file, or a plugin. In this example I’m prefixing the functions with the wpdc_custom namespace. You can use whatever you like for the function names, as long as they don’t conflict with other function names on your site.

The first function lets any URL that has the query_var discourse_sso=1 be processed by WordPress. When that query_var is set, the WP Discourse plugin automatically redirects the request to Discourse, so it can’t be used as a way of getting unauthorized access to the site.

The second function makes sure that logged in users are not kept out of the site by the Restricted Site plugin’s user_can_access function. This is necessary for the SSO client functionality to work. The function could be refined to limit access only to certain users, for example, only users who have logged in through Discourse, or only users who have some kind of membership.

add_filter( 'restricted_site_access_is_restricted', 'wpdc_custom_restrict_access', 10, 2 );
function wpdc_custom_restrict_access( $is_restricted, $wp ) {
    if ( ! empty( $wp->query_vars['discourse_sso'] ) && 1 === intval( $wp->query_vars['discourse_sso'] ) ) {

        return false;
    }

    return $is_restricted;
}

add_filter( 'restricted_site_access_user_can_access', 'wpdc_custom_user_can_access' );
function wpdc_custom_user_can_access() {
    if ( is_user_logged_in() ) {

        return true;
    }

    return null;
}

On the page that I’ve set for the Restricted Notice Page, I’m not using the [discourse_sso_client] shortcode. Using it works, but it will redirect the user back to the page that it’s included on. You can create an SSO login link that specifies the page you would like users to be redirected to. The link needs to be in this form:

<a href="http://example.com/?discourse_sso=1&redirect_to=http://example.com/">Login with Discourse</a>

Set the base URL of the href attribute to your site’s home URL. Set the value of the redirect_to parameter to the page that you would like users to end up on after they login through Discourse. In the example link above, users are being returned to the WordPress homepage after logging in.

In the next update to the plugin I’ll add a redirect_to option to the discourse_sso_client shortcode, so that you can use the shortcode and specify a redirect to URL.

One thing to note is that you can add a link in the form that I’ve given above directly to your Discourse forum, so that users can login to WordPress from the forum.

Let me know if this isn’t working for you, or if you run into any issues with it. I’ll keep the Restricted Site Access plugin activated in my development setup for the next few days to make sure I’m not finding problems with it.

4 Likes

Thanks so much for the help Simon, this should be a perfect solution. I will consult with the team working on it and if there are any questions they should be able to reply directly to this thread. :vulcan_salute::wink:

2 Likes

There’s an issue with the Restricted Site Access plugin blocking WordPress REST API requests. If you are publishing posts from WordPress to Discourse, and have enabled the WP Discourse Sync Comment Data webhook, you will need to modify the conditional statement in first function that I added. (The Sync Comment Data webhook makes the WP Discourse plugin a lot more efficient on busy sites.)

add_filter( 'restricted_site_access_is_restricted', 'wpdc_custom_restrict_access', 10, 2 );
function wpdc_custom_restrict_access( $is_restricted, $wp ) {
	if ( ( ! empty( $wp->query_vars['discourse_sso'] ) && 1 === intval( $wp->query_vars['discourse_sso'] ) ) ||
	     ! empty( $wp->query_vars['rest_route'] ) ) {

		return false;
	}

	return $is_restricted;
}

See this post for details: How to Allow REST API Requests While Restricted Site Access is Active - Philip Newcomer.

4 Likes

I implemented all of this and everything works perfectly. Thanks so much again for the help, it is much appreciated!

3 Likes