I've never been presented to a person who forgot their email address. Quite a claim you may say, but when one presents themselves in business one tends to shake hands and hand over a business card with the email written on it. Next time you are in a meeting ask someone what their OpenID URi is. You'll probably get a blank stare followed by an answer along the lines of "oh, ehm, I only have Skype".
The email address although geeky looking is now part of our daily lives unlike the OpenID URi, hence the challenge for those of us involved in developing OpenID solutions is to provide helpful usability centric solutions to this challenge. Given that, I challenged myself; can I provide an organisation with a mechanism to authenticate with OpenID but use the employees email address and email password? Here is my approach along with usability notes from testing.
A typical business email address looks something like this:
firstname.surname@example.com
OpenID has a consumer which is the web site that you want to authenticate to. It asks you for your OpenID which is typically a URi that looks something like this:
firstname.surname.openid_server_example.com
The first thing to notice is that they look alike to the average employee which gives them a great opportunity to confuse them. There is a far greater chance that they will forget their OpenID URi as it is not ingrained in their minds as with their email address. Instead of forcing them to learn their OpenID we should allow and forgive them for putting in their email address as their OpenID URi.
Option 1: Allowing email addresses to be entered instead of a Uri
In the OpenID consumer script we can look for an email address and replace with with an OpenID URi:
<?php
$email = "firstname.surname@example.com";
$company_email_server_url = "example.com";
$company_openid_server_url = "openid_server_example.com";
$pos = strrpos($email, $company_email_server_url);
$user = substr($email, 0, $pos-1);
$URi = $user . "." .$company_openid_server_url;
echo $URi; // will echo firstname.surname.openid_server_example.com
?>
We now had the URi back to the consumer and proceed with authentication as normal.
Option 2: OpenID assistance
With option 1 we have sort of shot ourselves in the foot because if your employees don't know that they have OpenID they do not get the full benefit of it (like being able to authenticate to an external website), hence my preferred method is to "guide" your employee in a helpful way.
Let them type in their email address but check for it:
<?php
$email = "firstname.surname@example.com";
$pos = strrpos($email, "@");
if ($pos === false) {
$URi = $email;
}
else {
$openid = str_replace("@", ".", $email);
echo "This looks like an email address. Perhaps your OpenID is " . $openid;
// return to form and prefill openid with $openid
}
echo $URi;
?>
If you find something that looks like an email address then suggest to them an OpenID URi equivalent.
Using their email password
On the OpenID server a form is included for the users password. Upon posting that we have both the URi (firstname.surname.openid_server_example.com) and the password. The password should match that of the users email password.
Checking username and password using LDAP
Many companies and organisations use an LDAP directory to hold email username and passwords. Here is an example of how to check using LDAP. Please note the code is here to demonstrate the idea simply. It is not robust nor secure.
The first bit of the email (firstname.surname) is the LDAP username so we need to get it.
<?php
$email = "firstname.surname@example.com";
$company_email_server_url = "example.com";
$pos = strrpos($email, $company_email_server_url);
$user = substr($email, 0, $pos-1);
echo $user; // will echo firstname.surname
?>
Once we have the username we can authenticate against the LDAP server.
<?php
// We connect anonymously and get username
$connect = ldap_connect($server, $port);
$bind = @ldap_bind($connect);
$search = ldap_search($connect, "dc=corp,dc=sample,dc=com", "uid=".$username);
$result = ldap_get_entries($connect, $search);
// We verify using password
$bind = @ldap_bind($connect, $result[0][dn], $password);
if (isset($bind)) {
$search = ldap_search($connect, "dc=corp,dc=sample,dc=com", "uid=".$username);
$result = ldap_get_entries($connect, $search);
if ($username == $result[0][uid][0]) {
echo "Authenticated.";
}
}
ldap_close($connect);
exit;
?>
If you don't use LDAP and you have an IMAP server you can simply name a connection and if it returns true then the username and password is valid:
<?php
$mbox = imap_open("{localhost:143}", $username, $password);
?>
Once the username and password is checked as valid you can then continue with the OpenID authentication process as usual.
As you maybe aware, we have a new OpenID server in our lab called "
Prairie". We are considering adding the LDAP server. Please let me know if this is something you would want because if we get a good level of feedback we'll add it.