Extension:SSL authentication

SSL Authentication is an extension that automatically logs users into the wiki using their SSL certificate. It uses mod_ssl in Apache to fetch the DN from the client certificate and maps that to a MediaWiki user name. All users are automatically logged in, and all users are required to use certificates. These certificates must be vouched for by one of the certification authorities on file, specified by  option. Wiki user names are taken from the user's certificate (SSL_CLIENT_S_DN_CN), and if that user name does not already exist, it is created.

I started this work for MediWiki version 1.5.3 and we have used it for some months. A couple of weeks ago, I discovered Extension:Shibboleth Authentication] by Djcapelis and wow! That made it easy to rewrite my code as an extension and upgrade to the latest MediaWiki version.

Over time more people have been contributing, and in particular I want to say thanks to Krzysztof Kozlowski and D.J. Capelis for their help.

I still have some minor things to work out. I now use firstname + lastname (or CN in the user certificate) to as the login name and uses DN for the real name, but firstname + lastname is probably not unique in a larger environment, DN should be but it's not usable as a user name in MW. Maybe an md5 hash of the DN, but that makes for an ugly user name... You probably know the best way to resolve this for your own environment.

As you can see, there are some glitches in this documentation and you are welcome to help. :-)

Clientside certificate and SSL
describe what clientside certificate and SSL is

Configure Apache
For a start, you need some prerequisites. First, you need certificates for all your users. Take a look at OpenCA or the swedish PrimeKey Solutions if you don't have certificates. Maybe windowscertificates can be used?

We use smartcards for all our users.

Then you need to configure your Apache to use SSL. This is my no-comments code for httpd.conf to setup this:

SSLEngine on SSLProtocol -all +TLSv1 +SSLv3 SSLCipherSuite HIGH:MEDIUM SSLProxyEngine off SSLCertificateFile /etc/apache2/ssl.crt/server.crt SSLCertificateKeyFile /etc/apache2/ssl.key/server.key SSLCertificateChainFile /etc/apache2/ssl.crt/ca.crt SSLCACertificateFile /etc/apache2/ssl.crt/ca-dskort.crt SSLOptions +StrictRequire +OptRenegotiate +StdEnvVars +ExportCertData SSLVerifyClient require SSLVerifyDepth 1 SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog /var/log/apache2/ssl_request_log  ssl_combined  Options None AllowOverride None Order allow,deny Allow from all SSLRequireSSL SSLRequire %{SSL_CLIENT_S_DN}  =~ m/.*serialNumber= $/ 

We use SSLRequire to restrict usage of our wiki to certain users, with certificates enrolled by our CA which is stored in SSLCACertificateFile. Find some unique thing or add all users DN in this list. If you have used SSL and client certificates, you know what to do.


 * See Apache Module mod_ssl documentation

LocalSettings.php
Add this to your LocalSettings.php to init the extension

require_once('extensions/SSLAuthPlugin.php');
 * 1) Load SSLAuthPlugin

$ssl_map_info = true;
 * 1) Feel free to use extra PHP code to munge the variables if you'd like
 * 2) Additionally if you wish to only map some of the name data, set this to true
 * 3) and either blank ssl_RN and ssl_email or comment them out entirely.


 * 1) Ssssh.... quiet down errors
 * 2) $olderror = error_reporting(E_ALL ^ E_NOTICE);

$ssl_RN = $_SERVER['SSL_CLIENT_S_DN'];
 * 1) Map Real Name from certificate
 * 2) Can be DN but is it right?


 * 1) MW username is required to map to something
 * 2) You should beware of possible namespace collisions, it is best to chose
 * 3) something that will not violate MW's usual restrictions on characters


 * 1) Just using Firstname + Lastname (CN) from Certificate 'will' make collisions... but what to use?
 * 2) UN could be md5-hash of DN, but its ugly to use...

$ssl_UN = $_SERVER['SSL_CLIENT_S_DN_CN'];

if ($_SERVER['SSL_CLIENT_S_DN_Email'] != '') $ssl_email = $_SERVER['SSL_CLIENT_S_DN_Email']; else $ssl_email = strtolower($firstname . '.' . $lastname . '@ds.se');
 * 1) Map e-mail to something close?


 * 1) Turn error reporting back on
 * 2) error_reporting($olderror);

SSLAuthSetup;
 * 1) Activate SSL Plugin

SSLAuthPlugin.php
Copypaste this code to the new file