Setting up a single-user OpenID serverEdit
These are notes made while setting up my own single-user OpenID server. I wanted to set up my own server for the same reasons stated by Christopher Niemira, author of phpMyID, who writes:
I really don't like the idea of coupling a theoretically decentralized framework to one of a handfull of third party providers (and giving them my account credentials).
I chose to use phpMyID because it was a very simple implementation with no dependencies (not even a database).
Preparation
Based on information found here and here I proceeded to do the following:
Generate en MD5 hash of:
- a username,
the_username - realm,
OpenID - password,
the_password
echo -n "the_username:OpenID:the_password" | md5
Installation
I then exported a copy of the latest version of the relevant files from phpMyID:
cd path/to/web/directory
sudo svn export https://www.siege.org/svn/oss/phpMyID/trunk/MyID.php id.php
cd path/to/configuration/directory
sudo svn export https://www.siege.org/svn/oss/phpMyID/trunk/MyID.config.php id_config.php
Three things to note:
- Use of
sudobecause I wasn't running as a user with write privileges - Renaming the files to
id.phpandid_config.phpfor aesthetic reasons - Storing the configuration file,
id_config.php, outside of the web root
This last point is just basic security practice whenever I'm forced to use PHP: passwords and other sensitive configuration should always be stored outside of the webroot, just in case there is ever a problem with the Apache/PHP configuration that might cause the files to be served up as raw text rather than executed as a PHP script. In this case the risks are mitigated by the fact that the password is not stored in the configuration file (only a hash is stored) but it is basic security practice to adopt a multi-layered "onion" approach that implements multiple, separate barriers to guard against breaches. If an attacker were to access the configuration file brute-forcing a working password would be fairly easy because the user name wouldn't be hard to guess, the realm is publicly discoverable, and the hash isn't even generated using a salt.
Configuration file changes
22,23c22,24
< 'auth_username' => 'test',
< 'auth_password' => '37fa04faebe5249023ed1f6cc867329b'
---
> 'auth_username' => 'example_username',
> 'auth_password' => 'example_hash',
> 'auth_realm' => 'OpenID'
38,40c39,41
< # 'nickname' => 'Joe',
< # 'email' => 'joe@example.com',
< # 'fullname' => 'Joe Example',
---
> 'nickname' => 'Wincent',
> 'email' => 'example@example.com',
> 'fullname' => 'Wincent Colaiuta',
44,46c45,47
< # 'country' => 'US',
< # 'language' => 'en',
< # 'timezone' => 'America/New_York'
---
> 'country' => 'ES',
> 'language' => 'en',
> 'timezone' => 'Europe/Madrid'
id.php changes
779c779
< if (! @include('MyID.config.php'))
---
> if (! @include('/full_path_to_conf_dir/id_config.php'))
Other set-up
The following HTML needed to be added to the page residing at my "identity" URL:
<link rel="openid.server" href="https://wincent.dev/id.php" />
<link rel="openid.delegate" href="https://wincent.dev/id.php" />
<meta http-equiv="X-XRDS-Location" content="https://wincent.dev/id.php" />
Results
To test the system I made my first post using OpenID-based authentication here. There are two problems with the result:
- The "from" line reads as http://wincent.dev/a/about/wincent/weblog/, which doesn't exactly make clear the identity of the poster; this is because it just redirects to my weblog at the other URL.
- The the user profile linked to from the comment doesn't include the extra information that I included in my configuration.
The second problem is probably a limitation of LiveJournal and there's not much that I can do about that. I decided to address the former problem by choosing a better URL for future identification. So I set up a simple page with the following content:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>example.com</title>
<link rel="openid.server" href="https://wincent.dev/id.php">
<link rel="openid.delegate" href="https://wincent.dev/id.php">
<meta http-equiv="X-XRDS-Location" content="https://wincent.dev/id.php">
</head>
<body>
<ul>
<li>Wincent Colaiuta's personal weblog: <a href="http://example.com/">example.com</a></li>
<li>Mac OS X software: <a href="http://wincent.dev/">wincent.dev</a></li>
</ul>
</body>
</html>
From now on when I sign in using that URL the identity should be much more intelligible.