How to use your Drupal site as an OpenID over SSL
GOAL(or better, the pretext): we want to authenticate ourselves on other sites with OpenID by only using our site address http://example.com
, and running our own OpenID Identity provider, authenticating to it over HTTPS.
So, as prerequisite for hosting your own OpenID Identity Provider, you want to enable SSL in your web server; this is not strictly needed, just recommended, we do this also because we get some bonuses.
Much of this info can be obviously adapted to other scenarios not involving Drupal (or even OpenID) at all.
Contents
Setting up SSL on Apache 2
To enable SSL in your webserver you need to have a Server Certificate, there are mainly two options:
- A self-signed certificate
- A certificate signed by a Certification Authority
Self-signed certificate
This option OK for testing purposes, or in the case of a personal server and when you trust yourself.
NOTE: some OpenID RPs (Relay Parties), do not support OpenID over SSL with self-signed certs, see this bug report; plus, some says it is not recommended anyways.
I'll show the configuration in this simpler case and list the difference in the case of a Server Certificate signed by a CA.
In order to make our self signed certificate, as described in /usr/share/doc/apache2.2-common/README.Debian.gz
aptitude install apache2 ssl-cert make-ssl-cert generate-default-snakeoil --force-overwrite
Enable the ssl module:
a2enmod ssl
To enable the default SSL site run:
a2ensite default-ssl
and check the setting in /etc/apache2/sites-enabled/default-ssl
To enable SSL for your VirtualHosts:
<VirtualHost *:80> [Your settings ...] </VirtualHost> <VirtualHost *:443> [Your settings ...] # Enable SSL SSLEngine On SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # MSIE 7 and newer should be able to use keepalive BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown </VirtualHost>
You could even split the common part for a VirtualHost into an a_vhost.conf file, put the SSL setup into a ssl-common.conf, copy those to some location like /etc/apache/includes and include all them with:
<VirtualHost *:80> Include includes/a_vhost.conf </VirtualHost> <VirtualHost *:443> Include includes/a_vhost.conf Include includes/ssl-common.conf </VirtualHost>
In /etc/apache2/ports.conf, add
NameVirtualHost *:443 Listen 443
Open TCP port 443 on your firewall if needed, in my case (I have a in-new chain for new connections) the rule looks like this one:
$IPT -A in-new -p tcp -m tcp --dport 443 --syn -j ACCEPT
Restart apache:
invoke.rc apache2 restart
Certificate signed by CAcert.org
If you want to pursue this option you can use CAcert.org.
The steps are roughly:
- Create an account
- Add a domain
- Generate a certificate
After you created your account on cacert.org, in order to add your domain example.org
you need to be able to get emails to addresses like root@example.com
or postmaster@example.com
, it is enough to run a mail server like Exim on the server only until you receive the verification email, no MX dns records are needed, normally.
After your domain has been added you can request a certificate, follow this guide if you want to use that certificate with multiple VirtualHosts in Apache, you will end up using the SubectAlternativeName SSL extension.
Put the generated certificate in example_server.pem, verify it:
wget http://www.cacert.org/certs/root.crt -O CAcert_root.crt openssl verify -CAfile CAcert_root.crt -purpose sslserver example_server.pem
copy the files in the right locations, and use these lines in the Apache config (check default-ssl
and the other VirtualHosts):
SSLCertificateFile /etc/ssl/certs/example_server.pem SSLCertificateKeyFile /etc/ssl/private/example_privatekey.key
OpenID Identity Provider
Here are some details about how OpenID works. OpenID is a solution to the Unified Authentication (or Single sign-on) problem, here is instead some discussion about foaf+ssl which is a solution for the connected Digital Identity problem (or WebID), and finally a talk about foaf+ssl compatibility with OpenID.
Using OpenID saves you from creating accounts (explicitly) on many sites which is good, but you might not want others to store and manage your digital identity, in this case rolling out your own OpenID Identity Provider is the solution, check also this interesting blog post.
If you want to put your OpenID (Personal) Identity Provider on something like openid.example.com
, setup a DNS record for it first, and then a VirtualHost in Apache, preferably with SSL.
Here's a list of OpenID Identity Server, I chose simpleid because it supports OpenID 2.0 specification, here are the install instructions for simpleid.
phpMyID is very interesting too because of its simplicity and because it uses HTTP Digest access authentication instead of redirecting to the Identity Server page, but it lacks OpenID 2.0 support for now.
Drupal and OpenID
To setup our Drupal site URL as our OpenID, we have to set the delegation to our OpenID Identity Provider, we can use the OpenID URL Drupal module for that, and set the needed URL as provided by simpleid (remeebering to use the HTTPS scheme):
OpenID Server: https://openid.example.com OpenID XRDS Location: https://openid.example.com/index.php?q=xrds/username
Note: We could have used Drupal itself directly as the OpenID Identity Provider with the OpenID Provider module, but it is not stable yet.
For the sake of symmetry, you can also make your (already existing) users authenticate on your Drupal site itself by using OpenID, support for this is in Drupal Core already, enable the OpenID module and set the Identity in your user setting to the one provided by your OpenID provider.
BIG MISSING PART: I haven't found a way to let visitors comment on my posts using their OpenID Identity in Drupal, while in WordPress it easy to do with the WordPress OpenID plugin.
Bonus: use Drupal over SSL
Now that you added SSL to authenticate with your own OpenID Identity Provider, you have also the bonus of authenticating to Drupal via SSL if you want.
If you are using an explicit $base_url
you may want to use this snippet in your settings.php:
if (!empty($_SERVER['HTTPS'])) { ini_set('session.cookie_secure', 1); $base_url = 'https://example.com'; } else { $base_url = 'http://example.com'; }
Now, after checking that SSL is enabled in your VirtualHost
for your Drupal installation, go to https://example.com
and see if everything is working.
If you get a message from your browser about the page being "partially encrypted", maybe some of the resources of your page are still served using the http scheme, you can find out what by using Firebug (for Firefox), specifically its Net tab: look at the URLs of all the resources loaded to display the page, spot those served via http or coming from external sites. Fix this to be nicer to your visitors; even if this doesn't affect security, it looks unprofessional.
To make sure all the files download you link manually in your content are served over https, you can use use pathfilter files:
pattern to make sure the URLs get the right prefix, or use base_path() or url() when you write an url in php snippets.
You can also use the Secure Pages modules to restrict SSL only to the minimum required (login form and maybe administration pages) so to save some cycles on your server and some bandwidth.
Note: unfortunately filters in translated blocks in Drupal are currently broken, see http://drupal.org/node/674374
Extra: enable OpenID access in MediaWiki
There is also an OpenID authentication module for MediaWiki http://www.mediawiki.org/wiki/Extension:OpenID but I am not using it yet for this personal wiki. Here's some info about its installation.