Wednesday, January 21, 2009

Casify MediaWiki with phpCAS

This recipe attempts to cover the steps necessary to secure MediaWiki, the popular wiki originally developed for Wikipedia, using Central Authentication Services (CAS). CAS provides single-sign-on authentication -- log into one of your applications and be automatically authenticated with the rest.

Let me start by pointing out that these instructions only cover getting the user authenticated. It does not include information related to authorization -- i.e., role-based access, etc. After following these steps the Wiki will only be readable to users that have successfully logged in, and users that can't log in won't be able to read the wiki. See LocalSettings.php, below, on some options to make it readable to anonymous users. If you need role-based access this is probably a good starting point anyway.

These steps were developed using information from the following sources:

The case.edu site contains a page with general instructions on how to implement external authentication for MediaWiki. Its not CAS specific, but provides a good basis for integrating the CAS client, phpCAS.

I'll assume you already have MediaWiki up and running, but as a bit of background here are some details on my setup. I'm running Debian "Lenny" with PHP5 and MySQL-Server-5.0. I was able to get MediaWiki installed using 'apt-get install mediawiki. With this method the MediaWiki install location is /var/lib/mediawiki. On other distributions, or if installed manually, the location is likely different.

Copies of all the files mentioned below are contained in a zip archive available here.

Step 1, Install phpCAS.


Take a close look at phpCAS requirements and decide which extra php packages should be installed. I decided to install the following additional debian packages as a result.

php5-curl, php5-gd, php5-mysql, php-db, php-pear, php-xml

Then follow the instructions here for installing phpCAS on your system.

Step 2, Create the CasAuthentication extension for MediaWiki


In this step we take the code from step 2.3 in the case.edu instructions and create CasAuthentication.php in the MediaWiki extensions folder. Change the class name from MyAuthPlugin to CasAuthPlugin, but don't make any other changes now.

Take a look at the initUser() function -- you will eventually want to update the code here to provide the correct name and email for the user. CAS only provides us with the user login name, or 'NetID' in CAS terms, so its here that you would have to look up the user information in a database or via LDAP, etc. I leave this as an exercise to the reader since its very site-specific.

Step 3, Create CAS login scripts


In the MediaWiki installation directory (/var/lib/mediawiki on debian) create a subdirectory named 'login'. Copy cas1.php and cas2.php into this directory. The file cas1.php is a slightly modified version of the code listed in step 2.4.1 of the case.edu instructions. I was unable to store the Http-Referrer in the session and have it persist until the end of the login sequence, so my version passes the referrer as a request parameter instead. The file cas2.php is a combination of the phpCAS simple client demo and the code listing from case.edu's step 2.4.2.

Step 4, Enable URL Rewrites


URL re-writing is used to invoke the cas php scripts instead of the default MediaWiki login page. The instructions in this recipe assume that the base URI of the wiki has been configured to /wiki -- i.e., that you get to it using http://localhost/wiki. If not the rewrite rules will have to be adjusted accordingly. On my debian system, the Apache config directives for MediaWiki are in /etc/apache2/conf.d/mediawiki.conf. Add the following rewrite rules in the <Directory> for the MediaWiki installation location (e.g., /var/lib/mediawiki):

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/wiki/index.php$
RewriteCond %{QUERY_STRING} ^title=Special:Userlogin
RewriteCond %{REQUEST_METHOD} ^GET$
RewriteRule ^(.*)$ /wiki/login/cas1.php [R,L]

RewriteCond %{REQUEST_URI} ^/wiki/index.php$
RewriteCond %{QUERY_STRING} ^title=Special:Userlogout
RewriteCond %{REQUEST_METHOD} ^GET$
RewriteRule ^(.*)$ /wiki/login/cas2.php?logout [R,L]

Note that the second rule causes the logout link in MediWiki to invoke CAS logout. This may or may not be what you want.

Step 5, Configure LocalSettings.php


Add the following lines at the end of MediaWiki's LocalSettings.php file. Change the casServerHostname, casServerPort, casServiceUri and wgLoginFormKey values.


### BEGIN CAS CONFIGURATION ####

require_once "$IP/extensions/CasAuthentication.php";

$wgAuth = new CasAuthPlugin();

// CAS server hostname
$casServerHostname = 'cas.example.com';

// CAS server port. This is usually 443
$casServerPort = 443;

// This is the CAS web-application context URI
$casServiceURI = '/cas';

$wgLoginFormKey = "dC989kw6j0E41HN4I24E"; // Random key, change this

# AUthentication changes
$wgGroupPermissions ['*']['read']=false; // True here makes the wiki readable by anonymous users
$wgGroupPermissions ['*']['edit']=false;
$wgGroupPermissions ['*']['createaccount']=false;
$wgWhitelistRead = array("Special:Userlogin");

### END CAS CONFIGURATION ####


Restart Apache and if everything has been configured correctly you will be automatically redirected to the CAS page for MediaWiki logins, and upon success you should be redirected back to the referring URL.

Ken