I figured this new shiny
OpenID thing
was cool enough to start using it. There's just this one problem: I
didn't want to have to go through the "register on a website and
remember yet another password" dance once more; and since I have this
marvellous Kerberos realm set up which works for authenticating against
my webserver, too, why not use that?
So I downloaded the
JanRain PHP
OpenID library, and went hacking. It's not all that hard,
really:
diff -ruN ./lib/actions.php /svr/www/openid.grep.be/data/lib/actions.php
--- ./lib/actions.php 2006-12-08 23:56:22.000000000 +0100
+++ /svr/www/openid.grep.be/data/lib/actions.php 2007-03-08 14:18:32.000000000 +0100
@@ -88,17 +88,24 @@
if (!isset($input['openid_url']))
$errors[] = 'Enter an OpenID URL to continue';
- if (!isset($input['password']))
- $errors[] = 'Enter a password to continue';
+ if (!isset($input['password']) && !isset($_SERVER["REMOTE_USER"]))
+ $errors[] = 'Enter a password to continue, or log in using an ' .
+ 'apache logon method';
if (count($errors) == 0)
$openid_url = $input['openid_url'];
$openid_url = Auth_OpenID::normalizeUrl($openid_url);
- $password = $input['password'];
- if (!checkLogin($openid_url, $password))
- $errors[] = 'The entered password does not match the ' .
- 'entered identity URL.';
-
+ if(isset($_SERVER["REMOTE_USER"]))
+ if(!checkUser($openid_url, $_SERVER["REMOTE_USER"]))
+ $errors[] = 'The apache user does not match the openid URL';
+
+ else
+ $password = $input['password'];
+ if (!checkLogin($openid_url, $password))
+ $errors[] = 'The entered password does not match the ' .
+ 'entered identity URL.';
+
+
return array($errors, $openid_url);
@@ -166,4 +173,4 @@
return sites_render($sites);
-?>
\ No newline at end of file
+?>
diff -ruN ./lib/render/login.php /svr/www/openid.grep.be/data/lib/render/login.php
--- ./lib/render/login.php 2006-12-08 23:56:22.000000000 +0100
+++ /svr/www/openid.grep.be/data/lib/render/login.php 2007-03-08 14:53:56.000000000 +0100
@@ -3,6 +3,7 @@
require_once "lib/session.php";
require_once "lib/render.php";
+if(!isset($_SERVER["REMOTE_USER"]))
define('login_form_pat',
'<div class="form">
<p>
@@ -31,6 +32,33 @@
</form>
</div>
');
+ else
+define('login_form_pat',
+ '<div class="form">
+ <p>
+ Enter your identity URL into this form to log in to this server. This
+ server must be configured to accept your identity URL. Since you already
+ logged on through an Apache method, entering a password is not required
+ </p>
+
+ <form method="post" action="%s">
+ <table>
+ <tr>
+ <th><label for="openid_url">OpenID URL:</label></th>
+ <td><input type="text" name="openid_url"
+ value="%s" id="openid_url" /></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <input type="submit" value="Log in" />
+ <input type="submit" name="cancel" value="Cancel" />
+ </td>
+ </tr>
+ </table>
+ </form>
+</div>
+');
+
define('login_needed_pat',
'You must be logged in as %s to approve this request.');
@@ -62,4 +90,4 @@
return sprintf("<ul class=\"error\">\n%s</ul>\n", $text);
-?>
\ No newline at end of file
+?>
diff -ruN ./lib/session.php /svr/www/openid.grep.be/data/lib/session.php
--- ./lib/session.php 2006-12-08 23:56:22.000000000 +0100
+++ /svr/www/openid.grep.be/data/lib/session.php 2007-03-08 14:34:49.000000000 +0100
@@ -129,6 +129,16 @@
/**
+ * Check whether the logged-on user matches the specified OpenID URL
+ */
+function checkUser($openid_url, $user)
+
+ global $openid_user_urls;
+ return isset($openid_user_urls[$openid_url])
+ && $user = $openid_user_urls[$openid_url];
+
+
+/**
* Get the openid_url out of the cookie
*
* @return mixed $openid_url The URL that was stored in the cookie or
@@ -202,4 +212,4 @@
-?>
\ No newline at end of file
+?>
It expects an array in
config.php like so:
openid_user_urls = array(
"http://wo.uter.be/" => "wouter@GREP.BE"
);
(in the case of kerberos; if you use a different authentication
method, the syntax of that array will most likely be different, too)
It's still not perfect; all my changes really do is bypass the
password check if it notices that apache has already authenticated the
remote user; but I still need to "log on" at the PHP level, which also
requires me to enter my OpenID URL. A somewhat cooler implementation
would pre-enter the OpenID URL in the form. A really cool implementation
would not even show me the logon form, but go straight to the "logged
on" state, using the OpenID URL as given by the consumer, and the
information apache provides us on the remote user. But it's a start.
Adding OpenID capabilities to my blog comment entry script is proving
slightly more challenging, however. More on that later.