Mediawiki and Azure AD Single Sign On

W e wanted to build our Intranet solution and wiki seemed like a good choice. We chose to use mediawiki, the most popular wiki engine. We set it up using a standard Bitnami installation found on AWS marketplace. At the time we set this up, we were on version 1.31 of mediawiki. To ensure ease of use of the same, we also set up single sign on integration for the same. Find our journey to setting up single sign on with Azure AD. This post assumes a standard bitnami mediawiki over apache2 on a Ubuntu 16.04 machine. But the links provided in this post should help for other variations.

Mediawiki Setup (High Level Set up)

  1. If you do not have an AWS account, sign up for on
  2. Log into the AWS Console
  3. In the same browser window, search for aws marketplace
  4. Search for bitnami mediawiki subscribe to the software, choose your machine and aws region and launch via web.
  5. If you create new secure keys, do download the pem file to be used in putty to securely log into the machine
  6. Do install into the right VPC, subnets etc.
  7. You can track the initiation of the machine from the EC2 portal.
  8. Go to the EC2 portal and get the username (usually user) and password. See How to get bitnami credentials? for more information
  9. Log into the Ubuntu machine. See instructions at Connect to your Linux instance for more information. User name will be bitnami (See Connect to Bitnami Virtual machine for more information)

Generating a Certificate

  1. Log into the machine using putty (from a Windows machine) or another mechanism
  2. Here will use a the letsencrypt script for generating a certificate. (You can use other mechanisms to generate the certificate or buy one)
  3. Use the following set of commands to generate certificates
cd /tmp
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto
cd /tmp/letsencrypt/
./letsencrypt-auto certonly --webroot -w /opt/bitnami/apps/mediawiki/htdocs -d int.example.com

4. The above commands will generate the certificates and place them in the directory /etc/letsencrypt.

5. You will see that certificates have been generated in the folder /etc/letsencrypt/live/int.example.com. (You might need to have root access to be able to cd into and view this)

6. References: https://community.bitnami.com/t/let-s-encrypt-on-bitnami-mediawiki-image/45038/3

7. Note: You may need to have all your ports opened for this to work correctly. In AWS, you may want to navigate to the security group and allow all traffic (in and out). See AWS documentation for opening ports

Installing Certificate on the Apache Server

  1. Copy the certificates to the Apache config folders with the following commands
cp /etc/letsencrypt/live/int.example.com/fullchain.pem /opt/bitnami/apache2/conf/server.crt
cp /etc/letsencrypt/live/int.example.com/privkey.pem /opt/bitnami/apache2/conf/server.key

2. Restart your apache server using the following command

sudo /opt/bitnami/ctlscript.sh restart apache

3. Now you should be able to access your mediawiki installation at https://int.example.com.

Redirecting from port 80 to 443

  1. Users typically access http://int.example.com but this is an insecure port. Hence, you will need to redirect all users from port 80 to port 443.
  2. You will need to modify the file bitnami.conf to redirect traffic from port 80 to port 443. See instructions at Force http to https.
  3. Use the following commands (with vi as editor)
cd /opt/bitnami/apache2/conf/bitnami
vi bitnami.conf
... Modify file as in step #4 ...
sudo /opt/bitnami/ctlscript.sh restart apache

4. Add the following lines under the VirtualHost directive for port 80

  RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L

5. Restart the apache server using the command as in #3

Installing SimpleSamlphp

  1. Now, we can install simplesamlphp
  2. You can get the download link by click on the archive link and getting the URL for the latest version. Use the following commands to download and install the simplesamlphp library. See link
cd /tmp
wget https://github.com/simplesamlphp/simplesamlphp/releases/download/v1.16.2/simplesamlphp-1.16.2.tar.gz
tar xzf simplesamlphp-1.x.y.tar.gz
sudo mv simplesamlphp-1.16.2 /etc/simplesamlphp

3. Navigate to your document root at /opt/bitnami/apps/mediawiki/htdocs

4. Add a soft link to simplesaml application with the following command

ln -sf /etc/simplesamlphp/www simplesaml

5. Now, you should be able to access the simlpesaml application with the link https://int.example.com/simplesaml

6. Modify the config file to change the password for simplesaml tool portal

cd /etc/simplesamlphp/config
vi config.php

7. Find the line ‘auth.adminpassword’ => ‘123’,

8. Change the password from 123 to say password or some other password. Best to choose a password that nobody can guess

9. Restart your apache server with the following command

sudo /opt/bitnami/ctlscript.sh restart apache

Importing Metadata into SimpleSaml

FederationData.xml
  1. When users access your page, they will need to be redirected to Azure for authentication.
  2. To permit your application to access your Azure AD sign on page, you will need to provide some metadata for simplesaml.
  3. Head over to your Azure portal. Login as an administrator with the right permissions

4. Click on Azure Active Directory -> App Registrations -> Endpoints

5. Copy the URL where you can access your FederationMedata.xml file.

6. Paste the URL in a new window to get the FederationMetadata.xml file

7. Right click and save the XML file as FederationMetadata.xml file.

8. Now head back to the simple saml tool at http://int.example.com/simplesaml

9. Choose the Federation tab and then click the XML to SimpleSAMLphp metadata converter link

10. Paste the XML contents of the FederationMetadata.xml file

11. Click Parse to convert it to simplesamlphp format

12. Copy the contents of the parse data in the window named saml20-idp-remote

13. Head back to your putty session. Use the following commands to store the metadata for simplesaml to access

cd /etc/simplesamlphp/metadata
vi saml20-idp-remote.php

14. Paste the contents (metadata in php format) and save the file

15. For future use note down the link in the first line of the metatata — eg. https://sts.windows.net/54526d45-a91c-432a-a023-49951efeadb5/

Azure AD Single Sign On Set up

  1. Next, head over to the azure portal (portal.azure.com)
  2. On the left side click on Azure Active Directory. Select App Registrations and View All Applications.
Azure Portal App Set up

3. Select New Application Registration

4. For Name provide a name of your choice — eg. Example.com wiki

5. The home page URL for your wiki (Note that you should have, by now, set up a CNAME to redirect the URL to your AWS EC2 host)

6. Click Create at the bottom to create your wiki. It will lead you to the page as shown below

7. Click on Settings. Keep this page/tab open since we will need to come back to this

8. Note down the GUID that is the Application Id

Setting up simplesamlphp configuration

  1. Now head back to your putty session. Use the following commands to set up the configuration for simplesamlphp
cd /etc/simplesamlphp/config
vi authsources.php

2. Find the section for default-sp (‘default-sp’ => array)

3. Set the value of entityId as the value of the application id from Azure portal. Prefix this with the string spn. Eg. — spn:7a5976f1-bbb0–40ef-9d85-d80b3b70bac7

4. Set the value of idp to the value we noted down from the converted federationmedata.xml file — eg. https://sts.windows.net/54526d45-a91c-432a-a023-49951efeadb5/

5. Leave the rest of the parameters as is. Save the file and exit the editor

6. Restart your apache server as done before

7. Head over to the Azure portal. Go to App Registrations. Then click on the View All Applications and choose your application Example.com wiki. Click Settings followed by Reply URLs.

8. Remove the existing value for the ReplyURL and replace with https://int.example.com/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp as shown below

9. Now access your simplesaml web link at https://intranet.vivriticapital.com/simplesaml

8. Navigate to the Authentication tab. Click Test Authentication Sources

9. Click default-sp

10. This should lead you to the Azure AD/Office 365 sign in page. Login with your credentials

11. This should lead to a page as shown below. These are the values returned by the Identity Provider, MicroSoft, back to simplesampl and consequently your application

Simple SAML 2.0 Demo Example

12. Do take some time to go through these attributes since you will be using some of these when you set up the single sign on for your mediawiki site.

Install PluggableAuth and SimpleSaml mediawiki extensions

  1. PluggableAuth is an extension for mediawiki to use simplesaml based single sign on.
  2. Follow the instructions in the above page to download and install PluggableAuth and configure it. You can use these instructions to configure PluggableAuth. You can leave out $wgPluggableAuth_Class set up for now. We will deal with it in the next step.
  3. Next, download and install the SimpleSaml mediawiki extension as outlined in the link.
  4. Configure both the plugins as explained in the next few steps.
  5. First configure mediawiki options. Instructions and information can be found on the User Rights wiki
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['user']['edit'] = true;
$wgGroupPermissions['*']['createaccount'] = true;
$wgGroupPermissions['*']['autocreateaccount'] = true;

6. The first line forces users to log in before they can edit or contribute to page. If they are not logged in, then they will only be allowed to read and not contribute

7. The second line allows all users to edit though this line isnt really needed

8. The next two lines allows autocreation of accounts. So, once Azure AD authenticates users, an account will automatically be created if it doesnt exist for a given user.

9. Next, we will configure PluggableAuth

wfLoadExtension( 'PluggableAuth' );
$wgPluggableAuth_EnableAutoLogin = false;
$wgPluggableAuth_EnableLocalLogin = false;
$wgPluggableAuth_EnableLocalProperties = true;
$wgPluggableAuth_ButtonLabelMessage = 'Login';
$wgPluggableAuth_Class = 'SimpleSAMLphp';

10. First line adds the extension PluggableAuth.

11. If EnableAutoLogin is true, then users will automatically be logged in. Else, they will need to click on the login link and log in. So, it allows users to be in either read only or edit mode.

12. EnableLocalLogin provides users the option of logging in directly using the mediawiki user table. This may needed for the primary administrator login. So, I left it as is. There are other ways of achieving this too.

13. ButtonLabelMesage — an optional string for the label

14. $wgPluggableAuth_Class — Set this to SimpleSAMLphp for now. We will configure SimpleSAMLphp in the next few steps.

$wfLoadExtension( 'SimpleSAMLphp' );
$wgSimpleSAMLphp_InstallDir = '/etc/simplesamlphp';
$wgSimpleSAMLphp_AuthSourceId = 'default-sp';
$wgSimpleSAMLphp_UsernameAttribute = ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname','http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'];
$wgSimpleSAMLphp_EmailAttribute = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name';
$wgSimpleSAMLphp_RealNameAttribute = [
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'
];

15. First line adds the extension SimpleSAMLphp mediawiki extension

16. Second line provides the path to the SimpleSAMLphp installation. In our case, we have installed it in /etc/simplesamlphp

17. $wgSimpleSAMLphp_AuthSourceId provides the configuration group key under which we have added the authentication source. In our case we used default-sp

18. The next set of values defines the mapping between the attribute name-value pairs returned by Azure AD and mediawiki’s login parameters. You can refer back to the Simple SAML 2.0 Demo Example screen shot to see how this is set up.

19. $wgSimpleSAMLphp_UsernameAttribute — This is the name under which the wiki contributions will be displayed. So, it is best to keep these unique. Since Azure AD does not have a kerberos like unique name, we have used a combination of {firstname, lastname} aka {givenname, surname} for this field. The input is an array of these attribute values. I have also provided a modified version of the SimpleSAMLphp extension class that handles this. Code for the same is provided in the next section

20. Similarly, set up $wgSimpleSAMLphp_EmailAttribute and $wgSimpleSAMLphp_RealNameAttribute

21. Finally, we have changed the code a bit to suit Azure AD. Change directory to /opt/bitnami/apps/mediawiki/htdocs/extensions/SimpleSAMLphp. Open the file and find the following code snippet.

if ( isset( $GLOBALS['wgSimpleSAMLphp_UsernameAttribute'] ) ) {
if ( array_key_exists( $GLOBALS['wgSimpleSAMLphp_UsernameAttribute'],
$attributes ) ) {
$username = strtolower(
$attributes[$GLOBALS['wgSimpleSAMLphp_UsernameAttribute']][0] );
$nt = Title::makeTitleSafe( NS_USER, $username );
if ( is_null( $nt ) ) {
return false;
}
$username = $nt->getText();
$id = User::idFromName( $username );
} else {
wfDebug( 'SimpleSAMLphp: Could not find username attribute ' .
$attributes );
return false;
}
} else {
wfDebug( 'SimpleSAMLphp: $wgSimpleSAMLphp_UsernameAttribute is not set' );
return false;
}

22. Replace the above code snipped with the one below.

if ( isset( $GLOBALS['wgSimpleSAMLphp_UsernameAttribute'] ) ) {
$userNameAttribute = $GLOBALS['wgSimpleSAMLphp_UsernameAttribute'];
if ( is_array( $userNameAttribute ) ) {
$username = "";
foreach ( $userNameAttribute as $attribute ) {
if ( array_key_exists( $attribute, $attributes ) ) {
if ( $username != "" ) {
$username .= " ";
}
$username .= $attributes[$attribute][0];
} else {
wfDebug( 'SimpleSAMLphp: Could not find user name attribute ' .
$attribute );
return false;
}
}
} else {
if ( array_key_exists( $userNameAttribute, $attributes ) ) {
$realname = $attributes[$userNameAttribute][0];
} else {
wfDebug( 'SimpleSAMLphp: Could not find user name attribute ' .
$attributes );
return false;
}
}
} else {
wfDebug( 'SimpleSAMLphp: $wgSimpleSAMLphp_UsernameAttribute is not set' );
return false;
}

23. Restart the apache server with the command sudo /opt/bitnami/ctlscript.sh restart apache

Handling a bug

  1. See Known Bugs for more information on a bug that will cause this to not work.
  2. To handle this, make the following changes.
  3. Edit the LocalSettings.php file in the folder /opt/bitnami/apps/mediawiki/htdocs
  4. Change $wgMainCacheType = CACHE_NONE; to $wgMainCacheType = CACHE_DB;
  5. Edit the simplesaml config file in /etc/simplesamlphp/config/config.php
  6. Set the two values as shown below
'store.type'                    => 'sql',
'store.sql.dsn' => 'sqlite:/opt/bitnami/apache2/var/cache/sqlitedatabase.sq3',

7. Restart the apache server with the command sudo /opt/bitnami/ctlscript.sh restart apache

Testing and Usage

  1. You are all set now. You can now access your wiki at http://int.example.com.
  2. If you click on the Log In link on the right top corner, it should redirect you to your microsoft onlin login page. Once you login, you will be redirected back to the home page logged in with a user name
  3. A user account is created in the backend automatically

Happy Wikiying — Bye!