MediaWiki and Okta

At Spatial Networks we wanted to stand up a centralized content wiki to host internal information, as opposed to a bunch of individual documents — or separate wikis — for each team. One of the company requirements with any tool is that it needs to be integrated with the third-party SSO provider Okta.

This post will cover how to configure MediaWiki and Okta SAML for SSO authentication.

When I started the process of setting up a wiki to communicate with Okta as its authentication provider I started with the naive approach that it would be a simple manner of just updating one or two lines in an existing configuration file — all of which should take no more than an hour.

Oh, how wrong I was.

Over the many trials and errors (and errors) I was finally able to get a working MediaWiki with Okta SSO. Below are the high points.

Getting Started

Before going forward please familiarize yourself with my previous post that details setting up a Docker image with SimpleSAMLphp and Okta.

In addition to the above link, we will also be utilizing Docker Compose. Please see Install Docker Compose for setup instructions.

Using Docker with MediaWiki and SimpleSAMLphp

Final URLs for fully configured setup:

wiki URL: https://localhost:9000/wiki/

SimpleSaml: https://localhost:9000/simplesaml

Check out the Github repository:

git clone https://github.com/jwitrick/okta-mediawiki.git

In the checkout repository change to the directory mediawiki_okta/

First, let’s look at the Dockerfile and go over it block by block.

FROM jwitrick/okta-simplesamlphp as simplesamlphpFROM mediawiki:1.32.1

These lines will utilize public Docker images (hosted on Docker Hub) as our base image.

RUN apt-get update && \apt-get install -y — allow-unauthenticated libldap2-devRUN docker-php-ext-configure ldap && \
curl -sL https://deb.nodesource.com/setup_11.x | bash — && \
apt-get install build-essential nodejs -y && \
apt-get install sqlite3 libsqlite3-dev -y && \
docker-php-ext-install ldap
RUN docker-php-ext-install pdo pdo_mysql && \
docker-php-ext-configure pdo_sqlite && \
docker-php-ext-install pdo_sqlite

These commands will download and install required php components: sqlite, ldap, mysql as well as dependent OS packages.

COPY — from=simplesamlphp /var/simplesamlphp /var/simplesamlphpRUN cd /var/simplesamlphp && \
cp -r config-templates/acl.php config/acl.php && \
cp -r metadata-templates/* metadata/

These lines will copy the existing SimpleSAMLphp configuration from the Docker container unicon/simplesamlphp, as well as copy sample configuration files from the templates directory.

RUN mkdir /tmp/backup && \
mv /var/www/html/* /tmp/backup && \
mkdir /var/www/html/wiki && \
mv /tmp/backup/* /var/www/html/wiki/

Note: The public MediaWiki Docker image we are using is pre-configured to host the MediaWiki files as the home html path (http://<url>/), unfortunately due to the requirements of SimpleSAMLphp we have to change the host directory. So these lines will move all the contents of /var/www/html -> /var/www/html/wiki

RUN php -r "copy('https://extdist.wmflabs.org/dist/extensions/PluggableAuth-REL1_32-cdeff81.tar.gz', 'PluggableAuth-REL1_32-cdeff81.tar.gz');" && \
tar -xzf PluggableAuth-REL1_32-cdeff81.tar.gz -C /var/www/html/wiki/extensions && \
rm -rf PluggableAuth-REL1_32-cdeff81.tar.gz
RUN php -r "copy('https://extdist.wmflabs.org/dist/extensions/SimpleSAMLphp-REL1_32-72b213a.tar.gz', 'SimpleSAMLphp-REL1_32-72b213a.tar.gz');" && \
tar -xzf SimpleSAMLphp-REL1_32-72b213a.tar.gz -C /var/www/html/wiki/extensions && \
rm -rf /var/www/html/SimpleSAMLphp-REL1_32-72b213a.tar.gz

These lines download and install the required authentication extensions into the MediaWiki installation.

RUN ln -s /var/simplesamlphp/www /var/www/html/simplesamlphp

This line creates a symbolic link for /var/www/html/simplesamlphp to allow the url: http://<url>/simplesaml to be resolved.

RUN mkdir /var/simplesamlphp/data/db && \
chown www-data:www-data /var/simplesamlphp/data/db

Due to a known issue with MediaWiki sessions and SimpleSAMLphp, we have to utilize sql as the cache store. Further on in the post we will specify the cache session type and location, but for now these lines will create a directory on disk for it. For more information about the known issues with SimpleSAMLphp and MediaWiki please see: https://www.mediawiki.org/wiki/Extension:SimpleSAMLphp#Known_Bugs.

Note: If you plan on using an external storage location (mysql) instead of sqlite then these lines can be removed.

Build Initial Docker Image

Now to build the Docker image:

docker build -t mediawiki_okta .

At this point, we have an initial Docker MediaWiki image complete with SimpleSAMLphp.

For the next part (configuring MediaWiki and the database), we will utilize Docker Compose. The reason for using Docker Compose is so that we can deploy the running MediaWiki container and a database container together for things to work together.

The repository comes with a file stack.yml which is used by Docker Compose.

Create a compose file stack.yml with the following contents:

# MediaWiki with MariaDB and SimpleSAML
#
# Access via “http://localhost:9000”
# (or “http://$(docker-machine ip):9000” if using docker-machine)
version: ‘3’
services:
mediawiki:
image: mediawiki_okta
restart: always
ports:
- 9000:80
links:
- database
environment:
WIKI_PATH: '/wiki'
SIMPLESAML_PATH: '/simplesaml/'
BASE_URL: 'http://localhost:9000'
OKTA_METADATA_URL: 'https://<REPLACE_WITH_YOUR_SPECIFIC_SAML>/sso/saml/metadata' # Production Metadata
MEDIAWIKI_DATABASE_HOST: 'database'
MEDIAWIKI_DATABASE_USER: 'wikiuser'
MEDIAWIKI_DATABASE_PASSWORD: 'example'
MEDIAWIKI_DATABASE_NAME: 'my_wiki'
MEDIAWIKI_DATABASE_PREFIX: ‘wiki_’
volumes:
- ./volume:/var/www/html/wiki/images
# After initial setup, download LocalSettings.php to the same
# directory as this yaml and uncomment the following line and
# use compose to restart the mediawiki service
database:
image: mariadb
restart: always
environment:
# @see https://phabricator.wikimedia.org/source/mediawiki/browse/master/includes/DefaultSettings.php
MYSQL_DATABASE: my_wiki
MYSQL_USER: wikiuser
MYSQL_PASSWORD: example
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
volumes:
- ./mydatadb:/var/lib/mysql

In the newly created file, please update the variable: OKTA_METADATA_URL with the proper value of your application.

Initial Configuration of MediaWiki

Now let’s start the new Docker containers:

docker-compose -f stack.yml up

Open a web browser and navigate to http://localhost:9000/wiki

If all is working, you should see a page similar to:

Click on the link ‘setup the wiki

Setup the Database Configuration page like below:

Values are:

Database host: database
Database name: my_wiki
Database table prefix: wiki_
Database username: wikiuser
Database password: example

On the Database Settings page:

On the wiki Name page

Enter your information for the wiki configuration page. Please make sure to select: ‘Ask me more questions’ that way the wiki can be configured correctly.

On the wiki Options page

Choose the user rights option which makes the most sense for your use case. For my use case, I selected ‘Private wiki’ since I only want to allow authorized users to be able to read and edit individual pages.

For the ‘Copyright and license’ section you can leave the default option: No license folder.

For the ‘Email settings’ section you can do the setup which makes sense to you.

In the ‘Extensions’ section under the ‘Other’ title be sure to select the following:

  • PluggableAuth
  • SimpleSAMLphp

Note: I have also chosen to enable file uploads.

Please finish the wiki setup.

When the wiki installation is complete, you should see a page like:

Save the download file LocalSettings.php inside the wiki/ directory.

Custom SAML SSO Configuration Files

Now that we have a basic configuration for MediaWiki completed we can finish setting up SSO integration with OKTA.

  • There is a custom index.php file (html/index.php) which redirects users from the root URL (‘/’) to the wiki URL (‘/wiki’) automatically. This file will utilize environment variables BASE_URL and WIKI_PATH to properly redirect users.
  • By default the installed apache package will not be able to access the necessary files for SimpleSAMLphp to work. To that end, there is a customized file etc/apache2/conf-available/docker-php.conf which allows apache to access the SimpleSAMLphp files.
Alias /simplesaml /var/simplesamlphp/www
<Directory /var/simplesamlphp/www/>
Options -Indexes
AllowOverride All
Require all granted
</Directory>

Above was listing some customized files which were already complete, now for some required changes.

simplesamlphp/config/config.php:

  • Update the baseurlpath line with the following: 'baseurlpath' => getenv('BASE_URL') .''. getenv('SIMPLESAML_PATH'),
  • Search for enable.saml20-idp and change the value to true
  • Search for auth.adminpassword and change the value to a secure password.
  • Search for secretsalt and change the value to something random.
  • Search for store.type and change the value to be: sql
  • Search for store.sql.dsn and change the value to be: sqlite:/var/simplesamlphp/data/db/sqlitedatabase.sq3

simplesamlphp/saml-autoconfig.php

This change is optional.

$metadata_url_for = array(
'example-okta-com' => {metadata-url-From OKTA},
);

By default the configuration file will utilize the environment variable OKTA_METADATA_URL and set it to the key example-okta-com. You may rename example-okta-com to anything you wish, but if you do rename it then you will need to utilize the new name going forward.

Note: For Okta purposes, there is a customized MediaWiki extension file wiki/extensions/SimpleSAMLphp/includes/SimpleSAMLphp.php to allow the code to use an array to specify the MediaWiki Username. The updated code is in the function getUsername.

Customize LocalSettings.php for Okta SSO

Up to now all the changes have been to allow SimpleSAMLphp to communicate with Okta for SSO authentication, but now we have to customize MediaWiki to ensure it properly authenticates with Okta.

Modify the wiki/LocalSettings.php file (the one created during MediaWiki setup with the following:

Ensure all default user rights permissions are configured so users MUST log in, and also so it prevents local account creation. This is done by ensuring the following lines are in the configuration file (and that there are not conflicting entries).

$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['user']['edit'] = true;
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['autocreateaccount'] = true;
$wgGroupPermissions['*']['read'] = false;

Ensure the settings for PluggableAuth plugin are properly set:

$wgPluggableAuth_EnableAutoLogin = false;
$wgPluggableAuth_EnableLocalLogin = false;
$wgPluggableAuth_EnableLocalProperties = true;
$wgPluggableAuth_ButtonLabelMessage = 'Login';
$wgPluggableAuth_Class = "SimpleSAMLphp";

Ensure the settings for SimpleSAMLphp plugin are properly set:

$wgSimpleSAMLphp_InstallDir = '/var/simplesamlphp';
$wgSimpleSAMLphp_AuthSourceId = 'okta-sso';
$wgSimpleSAMLphp_RealNameAttribute = ["FirstName", "LastName"];
$wgSimpleSAMLphp_EmailAttribute = "Email";
$wgSimpleSAMLphp_UsernameAttribute = ["FirstName", "LastName"];

Let's go over these settings/values in-depth:

The line:

$wgSimpleSAMLphp_AuthSourceId = ‘example-okta-com’;

refers to the metadata key in the configuration files where MediaWiki can look up the correct Okta application metadata information.

In my last blog post we created an Okta SAML app and set the SSO URL to end in /example-okta-com as well as in the configuration file simplesamlphp/saml-autoconfig.php we specify the metadata key as example-okta-com. If you wish to change this value, it will need to be changed in all 3 places (Okta website, wiki/LocalSettings.php, and simplesamlphp/saml-autoconfig.php).

The lines

$wgSimpleSAMLphp_RealNameAttribute = ["FirstName", "LastName"];$wgSimpleSAMLphp_UsernameAttribute = ["FirstName", "LastName"];

indicate that MediaWiki should utilize the Okta Metadata keys ‘FirstName’ and ‘LastName’ when setting an authorized session. Unfortunately due to MediaWikis username limitations we cannot use the value of `Email` as the username (I believe it would have been perfect because that is always a unique key).

OPTIONAL: Okta Groups to Media Group mappings

It is possible for MediaWiki to automatically assign certain individuals to elevated groups (‘sysops’) based upon which group(s) they are assigned to in Okta. If this is something you are not interested in, please skip down to the Docker build section.

To configure Okta group ‘WikiAdministrators’ to MediaWikis ‘sysops’ group add the following entry to wiki/LocalSettings.php

$wgSimpleSAMLphp_GroupMap = ['sysop' => ['groups' => ['Wiki Administrators']]];

In order for that to operate you would have had to configure the Okta application to either:

A. Send all groups to MediaWiki (using the group Regex value of ‘.*’) or

B. Send groups if the Okta user is a member of the group that starts with ‘WikiAdministrators’

Update Okta Application RelayState

When the Okta application was first set up we either didn’t set up a ReplyState URL or we used a temporary one. Now that we have a working application let’s update that value.

In the Okta Application set the RelayState URL to be:

http://localhost:9000/wiki/index.php/?saml_sso=example-okta-com

Note: If you changed the metadata key from example-okta-com to something else, you will also need to change it here.

Build Final Docker Image

In the provided Dockerfile the last 6 entries are all commented out, please un-comment them in order to have Docker automatically put the newly configured configuration files into the image.

Now build the Docker image:

docker build -t mediawiki_okta .

Once the above command finishes running, we will have a fully built Docker image for MediaWiki and Okta, and we can test it.

Stop the running containers: docker-compose -f stack.yml down

Start a new set of containers: docker-compose -f stack.yml up

Navigate to the URL: http://localhost:9000/

If all is set up correctly it should automatically redirect you to http://localhost:9000/wiki/

If you click on the Login link you should be presented with your Okta applications login page and after you successfully authenticate with Okta you should see the welcome page:

Conclusion

Together we have walked through a complete MediaWiki configuration, as well as Okta SSO integration. I realize there are most likely better ways to do some of the configurations (and my solution won’t work for everyone), but I hope it’s helpful enough to allow you to get a jump start on integrating Okta SSO with MediaWiki…. And that it saves you days of self-starter work (and FRUSTRATION).

--

--