How to use your Drupal site as an OpenID over SSL

From ao2Wiki
Jump to: navigation, search

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.

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.