PHP, Zend Framework and Other Crazy Stuff
Archive for February, 2007
Zend_Service_Yadis Proposal
Feb 22nd
As part of the overall OpenID support goal, I have just formalised my proposal to support a Yadis Service in the Zend Framework and added to the ZF Wiki. If you wish to review and comment, the url is: Zend Framework Proposals: Zend_Service_Yadis – Pádraic Brady. If you don’t have a Wiki account you can add your comments to this blog entry.
The current approach focuses exclusively on the URL. I know there has been lots of progress regarding XRI, i-names, ILI and even an SMTP extension to Yadis however these will be dealt with once the main specification is implemented assuming demand and providers exist. Of course this all assumes the Proposal will even be approved
. As some are aware the roadmap to Zend Framework 1.0 is very tight, so my main aim is get the proposal to the Laboratory stage along with a few others I’ll propose in coming days and weeks.
Post 1.0 should hopefully see these components then reaching the Incubator within Zend Framework releases. In the meantime I’ll be setting up a more independent Subversion repository – a lot of the code has been occupying a QGL branch for convenience sake to date.
Edit: The initial source code is now being committed to http://svn.astrumfutura.org/zendframework/trunk/library/Zend/Service/, so you can export the entire trunk tree to see how it all fits together. Just be aware only the main service class is remotely finished and awaiting its unit testing.
Yadis: Service Discovery for Identities like OpenID (Part 2)
Feb 21st
Service Descriptions – The Yadis Resource Descriptor (XRD)
After all this fuss and running about, it’s easy to miss the point of Yadis – getting that final Yadis XRD document that describes the Services associated with a given ID. Sticking with our OpenID example, we know that in order to start authenticating a user on an OpenID Server, we need a few bits of information:
1. The OpenID Server URL; the URL to which HTTP requests will be made.
2. The OpenID Delegate: The ID of the current user on the OpenID Server (not their alias!)
3. The OpenID Service Types offered: For OpenID, this can include Signon 1.0, Signon 1.1 and Simple Registration (sreg) 1.0.
Here’s an example XRD document a website might fetch when performing Service Discovery:
[geshi lang=xml]
xmlns:openid="http://openid.net/xmlns/1.0"
xmlns="xri://$xrd*($v*2.0)">
[/geshi]
I’ll skip the details of parsing XML – you can use PHP dom or SimpleXML in PHP5. The XML document follows the XRD format, included in a current OASIS specification. At it’s most basic, the XRD document (noting these requirements are for Yadis 1.0 only) must contain a single XRD element composed of one or more Service elements. Each Service element defines a Service, as detailed in its child Type elements.
The Type element must always contain a valid URL or XRI (don’t worry yet about the XRI bit – it’s a proposed addition compatible with the current URI and IRI specifications). The URL should point to a Service specification, and contain a Version. If you check above, our example OpenID Provider is offering Signon 1.0-1.1 and Simple Registration 1.0.
The URI element must contain a valid URL – this is the URL the services described by the Type values are provided from, i.e. it’s where a website supporting OpenID logins would send its association and/or authentication requests.
Finally, there is an optional element “openid:Delegate”. This namespaced element contains the OpenID URL a user’s OpenID Provider knows them as (remember, any other URL can be an alias but the OpenID Provider does not know or care about such aliases).
Conclusion
At the end of this Yadis introduction, I’ll refer anyone who’s stuck with it to the official Yadis Specification 1.0. It’s not a huge document, but has a few nuances I’ve likely skipped mentioning.
http://yadis.org/papers/yadis-v1.0.pdf
Next up I’ll jump into the details of OpenID!
Yadis: Service Discovery for Identities like OpenID (Part 1)
Feb 21st
Yesterday, I posted about my planned work on writing a PHP5 OpenID library. As I mentioned towards the end, I would be blogging about specific topics required for such a library. This first entry is an examination of Yadis, a Specification which is relied upon by OpenID. Of course Yadis is a topic of its own, since it is also used by Light-Weight Identity (LID), sxip Identity, and mIDm. You can bet more will join in once Yadis becomes more firmly established.
This post is mainly to introduce Yadis, and what my upcoming effort towards a Zend_Service_Yadis would entail performing. Part 2, later, will briefly examine the format of a Yadis XRD document and how it should follow the Yadis Specification 1.0.
So what is Yadis?
The purpose of Yadis is to specify a standard for enabling any party (“the Relying Party”) to obtain an XML document containing relevant details of a specific Service (“the Yadis Resource Descriptor”) which describes Service details such as Type, Url, and other optional data to be included in Service requests. If that’s mumbo jumbo, it’s easily explained with an example.
Let’s take OpenID. In OpenID, the Yadis ID is simply your OpenID URL. If you have a Livejournal Blog, for example, you can use your blog URL as an Identity for other websites which support OpenID authentication. These will fire off a request to your Identity Provider to check you out. The problem is that the website doesn’t know where to send the request – it needs to discover your Provider’s authentication service, a process called “Service Discovery”. Service Discovery is what Yadis is all about since it defines a standard HTTP GET process, and a standard Service data format (XML XRDS syntax) anyone can use.
Service Discovery
The Yadis Specification 1.0 describes all the steps a Relying Party needs to perform in order to obtain a description of the services associated with an ID. In our example, an OpenID URL will be associated with an OpenID Server URL which can be used by any website to authenticate a user.. Service Discovery describes the steps in finding out where that OpenID Server is located, i.e. its URL. In case you’re wondering, an OpenID URL could be subdomain on your OpenID Provider’s website, or even your own personal website URL – this is very different from the Service URL.
Performing discovery relies on finding a Yadis Resource Descriptor which details the Services associated with any Yadis ID. This document will be XML, using the Extensible Resource Descriptor (XRD) format (an OASIS specification). It’s a bit tricky to find the end YRD XRDS document, so bear with me as I describe the process.
The first step is to make a simple HTTP GET request to the ID (if a URL). For example, our OpenID URL. The response now needs to be examined. There are broadly three types of valid responses detailed in the specification:
1. An HTML document with a “head” element that includes a “meta” element with a http-equiv
attribute of “X-XRDS-Location”. The “content” attribute of this element should contain a URL pointing to the Yadis ID’s associated Yadis XRD Document. For example:
[geshi lang=xml][/geshi]
2. Any document, so long as the response-headers contain an “X-XRDS-Location” response-header whose value should contain a URL pointing to the Yadis ID’s associated Yadis XRD Document.
3. A document of MIME media type, “application/xrds+xml”. We’ll hit gold when we receive this one! It means we just received the XRD document we were looking for. The MIME type will typically be contained in the “Content-Type” response-header.
The Bread Crumb Trail
In the above, two of the valid responses to an initial HTTP GET request to a Yadis ID (the OpenID URL in our example) don’t provide the needed Yadis XRD document, but provide a means of figuring out its actual location. Typically Service Discovery under Yadis will require at least two HTTP GET requests – the first to find the XRD location, the second to actually fetch it.
The first valid response is often used when an OpenID URL is an alias. You can actually create any number of aliases (and hence any number of aliasing OpenID URLs) based on a personal URL using this method since the aliases can simply inform a website (via either a response-header or “meta” element) where to look for the underlying Service Provider’s XRD document. Of course the underlying XRD is specific to only one account – that URL or ID which your aliases are each aliasing. Last time I mention “alias” in case I get dizzy…;).
In short, the Yadis Specification ensures any Relying Party can follow the valid responses from one to another until they finally receive the required Yadis document. Of course, if someone throws a spanner in the works you should ensure an application doesn’t follow a circular trail until PHP bumps its max execution limit. The Yadis Specification is a bit vague, but in general if you make more than 4 HTTP requests then I’d suggest the Yadis process should be considered to have failed.
Part 2 continues by examining the Yadis XRD Document format…
PHP Magazine: PHP Game Poll
Feb 21st
http://www.php-mag.net/magphpde/magphpde_news/psecom,id,26905,nodeid,5.html
The International PHP Magazine has started a new poll asking readers to votes for their favourite PHP game. Judging by the list it looks like the top 10 Sourceforge registered open source games. I listed these a while back and noted phpDiplomacy in particular was doing really well. Somehow though I doubt the voting will be brisk. Should I tell them the QGL is not actually a game but a PHP game-oriented library?
.
OpenID library for the Zend Framework?
Feb 20th
A few months ago I was requested to add OpenID support (a growing trend) to a small website. Some of the members of the society whose website this is, were running blogs and Flickr sites and thought it would be “neat”. Being a fan of “neat” myself, I figured it would be reasonable to add, and indeed it was. I was using the JanRain PHP-Openid library seeing as it is likely the only full implementation in PHP so far.
Here in the present, everyone I work with is all too aware of OpenID. It’s been growing up, especially with the current 1.2 set of proposals, and of course support for OpenID is bound to be spurred higher by recent support announcements by Mozilla for Firefox 3, and Microsoft for Windows Vista. Also, the open Yadis specification is useful outside of OpenID for other things.
Loving PHP5 and being a long time OOP fanboy, I’ve decided to take on a small personal project – writing a strictly PHP5 library to support Yadis and OpenID respectively. Partly to learn the teeny details surrounding OpenID/Yadis, and also to add a pure PHP5 library which is strictly object oriented. Of course such an undertaking is a complete pain in the ass since OpenID requires a lot of functionality from cryptographic algorithms (HMAC/Diffie Hellman), big integer math (bcmath/gmp/big_int support) to simple things like making HTTP requests from PHP.
Enter the Zend Framework. The ZF has become central to no few of my projects. I also use other frameworks, but I just find the ZF hits the sweet spot a lot. Since the Zend Framework has a lot of independent components, relying on it lets me take advantage of components like Zend_Service_Abstract, Zend_Uri and Zend_Http_Client among others. If you’ve ever looked under the hood of the JanRain PHP-Openid library you’ll notice they implement *all* of this without a single dependency on PEAR or other external classes. I don’t want to repeat that practice here.
I guess I can be accused of “Not Invented Here” syndrome. I’m willing to plead guilty on that. In my defence, there exists only the one (AFAIK) php library dedicated to OpenID. It’s written in PHP4 and mixes procedural functions into it’s otherwise OOP approach. I found it unnecessarily complex and duplicative – a lot of its functionality is readily available from PEAR or other sources. But outside my personal impressions, I love tinkering with and learning the nitty-gritty of new ideas. I do hope the library will prove acceptable enough to eventually be added to the Zend Framework. Regardless of that suggestion I intend plundering the ZF for all its worth, and release everything under the New BSD license anyway.
In the meantime, as a bit of a brain dump exercise I’ll be posting a lot more about the technologies underlying OpenID. It’s a well documented area, but I doubt everyone reading this blog has the time to read through all the associated specifications and their recent proposal updates. Should be a fun journey – for me anyway
.
