What is this “Single Sign-On”
Wouldn’t it be nice if we didn’t have to remember so many passwords? With the proliferation of Software as a Service (SaaS) applications on the internet there are more and more things that we need to remember a username and password to access. This is where Single Sign-On (SSO) comes in. Single Sign-On is the idea that you can sign-on with one set of credentials and be signed-on to multiple services all at once.
Right now the most popular SSO implementation is OpenID. OpenID is a standard that defines how SSO id’s look and how you find who can verify an SSO id. OpenID’s typically look like a URL:
http://example.com/id/1234
But other services will accept an email address as the OpenID:
1234@example.com
In both cases example.com is the Identity Provider.
How it works
The service requesting the authentication is usually called the Relying Party, as they are relying on the Identity Provider to verify the end-user’s identity. The Relying Party needs to do a look up of the Identity Provider from the OpenID. The exact mechanics of this look up are outside the scope of this article (you can find libraries at the OpenID site), but the end result is that the end-user is sent to the Identity Provider (either through a redirect or a pop-up) to verify their identity.
Once the end-user has verified their identity the Identity Provider redirects them back to the Relying Party with information about the end-user’s identity. The Relying Party can then associate that with an authenticated account and sign-in the end-user.
Enough Talk, More Code
So lets get to brass tacks, how do you make your web site SSO aware? First things first you need to change your login screen so users know they can use their OpenID to sign-on to your site. Google has a great article on designing your login page.
Second, you are going to need a suitable library for doing the SSO discovery for you. While you can implement this yourself, it is highly recommended that you use a library that has been tested and is secure. A list of available libraries is available at the OpenID site. For these examples we are using the library from OpenId Enabled.
When you are parsing the passed in user credentials you want to look for valid OpenID’s or email addresses:
// See the examples/consumer/common.php file in OpenID Enabled library package.
// This provides some utility functions used below.
require_once 'common.php';
session_start();
// A variable to hold the domain from the OpenId we will use to discover the service.
$openid_domain = '';
// Check for email addresses. ex 1234@example.com
if (strpos($_POST['username'], '@') !== false)
{
$email_match = array();
// Our regular expression is designed to match most email address and get the domain portion.
preg_match('/.*@(.*)/', $_POST['username'], $email_match);
$openid_domain = $email_match[1];
}
// Check for url OpenID's. ex http://example.com/id/1234
elseif (strpos($_POST['username'], 'http') !== false)
{
$openid_domain = $_POST['username'];
}
We should now have in our hands a domain to send to our OpenId library so we can discover the OpenID Identity Provider. This is pretty straight forward:
if (!empty($openid_domain))
{
// If we found an OpenId domain try and discover the login service.
// To create the consumer we need to setup a store for the OpenID information
$store_path = '/tmp/_php_consumer_test';
$store = new Auth_OpenID_FileStore($store_path);
// Once we have a store for the information we need to create a new consumer.
$consumer =& new Auth_OpenID_Consumer($store);
// The GApps_OpenID_Discovery allows the consumer to find openid's for Google Apps.
new GApps_OpenID_Discovery($consumer);
// Try/Catch in case an exception is thrown.
try
{
// This is a call to the OpenID Enabled library. It translates our domain to a discovery request.
$auth_request = $consumer->begin($openid_domain);
}
catch (Exception $error)
{
// Execption handling
}
}
else
{
// Otherwise try regular login process
}
The $auth_request variable above holds an object that will be able to give us the url that we will redirect the end-user to so they can verify their identity.
So, let’s get that url:
// The url of your server. This is the address that the end-user will be redirected to after they verify their identity.
$server_url = 'http://myserver:80';
// Get the url to redirect the end-user. We need to pass the function our local server url and the location of the call back script the end-user should be redirected to.
$redirect_url = $auth_request->redirectURL($server_url, $server_url.'/callback.php');
// If the redirect URL can't be built, display an error message. This uses an OpenID Enabled static class.
if (Auth_OpenID::isFailure($redirect_url)) {
echo 'Could not redirect to server: ' . $redirect_url->message;
} else {
// Send redirect.
header('Location: '.$redirect_url);
}
At this point the end-user should be redirected to their Identity Provider to verify their identity. If they do so successfully they will be returned to our our call back url that we defined so that we can process the results.
We’ll cover those bits in Part 2.
2 Comments
Hi there,
I need to full class script of making the openid for the google, yahoo, facebook, twitter and linkedin.
Thanks,
Amit
NLv1Sx http://cje6CgslLk0ds3Nnto7djJaor.com
1 Trackbacks