Using Discourse SSO with Mediawiki

While trying to find ready-to-use solution I’ve seen multiple questions on Internet about that and at least one topic on this forum. I also need to integrate Discourse SSO with Mantis Bug Tracker so I decide to go with more generic code that I might reuse for Mantis as well. Code is very ugly, but it’s works and might help someone.

Read the instruction and activate SSO provider in Discourse

Install Auth_remoteuser extension for MediaWiki

More information about extension:
https://www.mediawiki.org/wiki/Extension:Auth_remoteuser
Make sure to check instructions so you can adjust it’s settings for your needs.

Mirror on GitHub:

You can clone extension from github into your wiki directory:

git clone https://github.com/wikimedia/mediawiki-extensions-Auth_remoteuser.git /path/to/mediawiki/extensions/Auth_remoteuser

Install Discourse SSO client script

  1. Get script from GitHub:
    GitHub - ArseniyShestakov/singlefile-discourse-sso-php: Ugly, but working single-file SSO implementation in PHP
  2. Copy discourse-sso.php into directory with your wiki.
  3. Edit defines on top of file according to your need.
  4. To create database table and test it visit https://your.wiki.domain/discourse-sso.php

You can check databse table contents from command line:

mysql -u wikiuser -pPASSWORD wikidb -e "SELECT * FROM sso_login;"

If everything is fine you’ll see username / email and other information here.

Edit LocalSettings.php

First of all make sure you set createaccount and autocreateaccount permissions properly:

// Forbid account creation by users
$wgGroupPermissions['*']['createaccount'] = false;
// Allow extensions to manage users
$wgGroupPermissions['*']['autocreateaccount'] = true;

After that you’ll need to add code like this to the end of wiki configuration file:

// Discourse authentification
require_once( "$IP/discourse-sso.php" );
$DISCOURSE_SSO = new DiscourseSSOClient();
$SSO_STATUS = $DISCOURSE_SSO->getAuthentication();
if(true === $SSO_STATUS['logged'] && !empty($SSO_STATUS['data']['username']))
{
        $wgAuthRemoteuserUserName = $SSO_STATUS['data']['username'];

        $wgAuthRemoteuserUserPrefs = [
                'email' => $SSO_STATUS['data']['email']
        ];
//        $wgAuthRemoteuserUserPrefsForced = [
//                'email' => $SSO_STATUS['data']['email']
//        ];

        if(!empty($SSO_STATUS['data']['name']))
        {
                $wgAuthRemoteuserUserPrefs['realname'] = $SSO_STATUS['data']['name'];
//                $wgAuthRemoteuserUserPrefsForced['realname'] = $SSO_STATUS['data']['name'];
        }
        wfLoadExtension( 'Auth_remoteuser' );
}

If you uncomment lines with force email / name will be changed not just for newly automatically-created users, but also for existing wiki users.

Test it

Now after you visit https://your.wiki.domain/discourse-sso.php you should be redirected to your wiki and you’ll be logged-in.

Redirect Login URL to SSO script:

I not yet find best easy to change login url so I just used following redirect via nginx:

        if ($request_uri ~* "^.*Special:UserLogin.*$") {
                return 302 https://your.wiki.domain/discourse-sso.php;
        }

To be continued…

This is only tested on wiki of project I worked on and likely . Use on your own risk!

I’ll try to improve this guide as soon as I find better ways to integrate it into Mediawiki.

15 Likes

Hi, I set up SSO for Discourse and Medaiwiki. When i click log in button it gives me 404 error:

**https://site.com/discourse-sso.php?sso=bm9uY2U9ZmM0ODkzYzMwZjE2ZDM1YWJkMDljN2E4NzczYzJkYmI2Y2FhNGU0ZDA3NTg5YTk1NzhkNDIxZWZkOGMyN2Y0OGRiYWViMzA4ZTIzOTQ0MzVkZmYxZTk5NmZmMDAxMGYzMDEyYjk1ZTllZGE0M2E5NTE3NjFkMzdiOGFjMjNkNTQmbmFtZT1TU08mdXNlcm5hbWU9c3NvdGVzdHVzZXImZW1haWw9cG9zdGElNDBnYW1lb2Z0aHJvbmVzdHIuY29tJmV4dGVybmFsX2lkPTEwNDM2JnJldHVybl9zc29fdXJsPWh0dHBzJTNBJTJGJTJGdmlraS5nYW1lb2Z0aHJvbmVzdHIuY29tJTJGZGlzY291cnNlLXNzby5waHAmYWRtaW49ZmFsc2UmbW9kZXJhdG9yPWZhbHNlJmdyb3Vwcz10cnVzdF9sZXZlbF8w&sig=6f21b389bc5bbbf8420addbe9ceacb0dbe6e6d5643a8aab66f20de6058b9ecd4**

HTTP ERROR 404

Any idea?

Edit: I checked database tables. There is no sso_login table in database. :frowning: I fixed it but

mysql> SELECT * FROM sso_login;
Empty set (0.00 sec)

I fixed that too. But still doesn’t work. User’s can’t login wiki after login to Discourse.

How exactly you fixed it? Database table supposed to be created on you manually run script by visiting it first time browser.

Can you clarify what exactly is wrong?

If it’s 404 then you need to make sure that discourse-sso.php file is located in right directory.

1 Like

First time, i set up wrong database informations. So database table can’t created. But i fixed. After that, i checked on terminal, table and user infromations created correctly.

I tried to create new user and login, user informations created on sso_login table but on the wiki not logged in. Discourse-sso.php file is located right directory and when i go wiki.site.com/discourse-sso.php its directing to Discourse login page. But cannot loggin in Mediawiki.

Ok if database is fine then SSO itself is working.
What Mediawiki version are you using right now? I probably should try to upgrade my own instance to latest version and check if something will break.

If you have some understanding of PHP you can try debug it on your own:

  • Make sure code for Auth_remoteuser is in the end of LocalSettings.php
  • Try to add something like var_dump($SSO_STATUS);exit; and check what it’s going to print when you going to wiki.
  • SSO code working fine and there is valid username then make sure Auth_remoteuser mediawiki extension is in proper directory and working fine.

Also feel free to can contact me via instant messenger if you need some assistance. You’ll find contacts via my profile.

1 Like

I use Mediawiki 1.25. I tried updating in the past. I had trouble with Composer. But I will try again. Also i will try debug.

Most likely old Mediawiki is the reason why it doesn’t work: Auth_remoteuser require 1.27+
https://www.mediawiki.org/wiki/Extension:Auth_remoteuser

I updated our wiki a year ago and it’s using 1.28.2.

1 Like

This explains everything.

I will try update my Mediawiki again. But I’ve had too many problems. I hope i will fix that problems.

I suppose it’s impossible to update OP with my current permissions so I’ll just share some useful details here.

So it’s end up Mediawiki actually using localized identifiers for special page URLs so redirect isn’t really an option once there is non-English UTF-8 in URL. Browsers tend to encode URLs and it’s tricky to make redirection work with either Nginx or Apache configuration.

So instead of adding redirect it’s possible to just hardcode url within Mediawiki in this file:

./includes/skins/SkinTemplate.php

Find (line 682 in my version):

                        $login_url = [
                                'text' => $this->msg( $loginlink )->text(),
                                'href' => self::makeSpecialUrl( 'Userlogin', $returnto ),
                                'active' => $title->isSpecial( 'Userlogin' )
                                        || $title->isSpecial( 'CreateAccount' ) && $useCombinedLoginLink,
                        ];

Then get it to look like this:

                        $login_url = [
                                'text' => $this->msg( $loginlink )->text(),
                                'href' => '/discourse-sso.php',
//                                'href' => self::makeSpecialUrl( 'Userlogin', $returnto ),
                                'active' => $title->isSpecial( 'Userlogin' )
                                        || $title->isSpecial( 'CreateAccount' ) && $useCombinedLoginLink,
                        ];
1 Like

It seems logout URL is missing on Mediawiki. Could it be related to SSO?

Edit: I seems Auth remote user extension causes it. Users can’t logout to wiki in this case. How i can fix that?

https://www.mediawiki.org/wiki/Extension:Auth_remoteuser

That one I didn’t solve since for my project it’s wasn’t important. If you have issues with security then it’s better to just patch SSO code to bind session to IP or reset auth after shorter period of time. After all it’s easy to login just by clicking on URL.

1 Like

That was bad. :frowning:

Curious how this is working out for you if you’re still using this.

Anyone using this “as is” ? in addNonce function, the query

$this->mysqli->query("INSERT INTO ".SSO_DB_TABLE." (`id`, `nonce`, `logged`, `expire`) VALUES (NULL, '$nonce', '0', '".$expire."');");

fails because : #1364 - Field 'admin' doesn't have a default value and actually, the definition for the field in $sqlStructure says admin Tinyint(1) NOT NULL :frowning:

(same for “moderator” field BTW)

Working code :slight_smile:

$this->mysqli->query("INSERT INTO ".SSO_DB_TABLE." (`id`, `nonce`, `logged`, `expire`,`admin`,`moderator`) VALUES (NULL, '$nonce', '0', '".$expire."',0,0);");`

I made a version of this that uses PostgreSQL and has functionality for logging out: GitHub - hhyyrylainen/singlefile-discourse-sso-php: Ugly, but working single-file SSO implementation in PHP

I hopefully didn’t make any security related mistakes.

3 Likes

Cool @Boost , you should push it back to master! Nice job and thank you.

1 Like